-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLVM][CodeGen][AArch64] while_le(#,max_int) -> all_active #111183
[LLVM][CodeGen][AArch64] while_le(#,max_int) -> all_active #111183
Conversation
When the second operand of an incrementing while instruction is the maximum value, comparisons that include equality can never fail.
@llvm/pr-subscribers-backend-aarch64 Author: Paul Walker (paulwalker-arm) ChangesWhen the second operand of an incrementing while instruction is the maximum value, comparisons that include equality can never fail. Full diff: https://github.com/llvm/llvm-project/pull/111183.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 48e1b96d841efb..2646db3d64b1d2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -5530,6 +5530,13 @@ static SDValue optimizeIncrementingWhile(SDValue Op, SelectionDAG &DAG,
SDLoc dl(Op);
APInt X = Op.getConstantOperandAPInt(1);
APInt Y = Op.getConstantOperandAPInt(2);
+
+ // When the second operand is the maximum value, comparisons that include
+ // equality can never fail and thus we can return an all active predicate.
+ if (IsEqual)
+ if (IsSigned ? Y.isMaxSignedValue() : Y.isMaxValue())
+ return DAG.getConstant(1, dl, Op.getValueType());
+
bool Overflow;
APInt NumActiveElems =
IsSigned ? Y.ssub_ov(X, Overflow) : Y.usub_ov(X, Overflow);
diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-while.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-while.ll
index 8380d5ca55cf29..ab4554428be450 100644
--- a/llvm/test/CodeGen/AArch64/sve-intrinsics-while.ll
+++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-while.ll
@@ -128,13 +128,12 @@ define <vscale x 16 x i1> @whilele_b_ii_dont_fold_to_ptrue_overflow() {
ret <vscale x 16 x i1> %out
}
-define <vscale x 16 x i1> @whilele_b_ii_dont_fold_to_ptrue_increment_overflow() {
-; CHECK-LABEL: whilele_b_ii_dont_fold_to_ptrue_increment_overflow:
+define <vscale x 16 x i1> @whilele_b_ii_known_always_true() {
+; CHECK-LABEL: whilele_b_ii_known_always_true:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #2147483647 // =0x7fffffff
-; CHECK-NEXT: whilele p0.b, wzr, w8
+; CHECK-NEXT: ptrue p0.b
; CHECK-NEXT: ret
- %out = call <vscale x 16 x i1> @llvm.aarch64.sve.whilele.nxv16i1.i32(i32 0, i32 2147483647)
+ %out = call <vscale x 16 x i1> @llvm.aarch64.sve.whilele.nxv16i1.i32(i32 2147483646, i32 2147483647)
ret <vscale x 16 x i1> %out
}
@@ -388,13 +387,12 @@ define <vscale x 16 x i1> @whilels_b_ii_dont_fold_to_ptrue_overflow() {
ret <vscale x 16 x i1> %out
}
-define <vscale x 16 x i1> @whilels_b_ii_dont_fold_to_ptrue_increment_overflow() {
-; CHECK-LABEL: whilels_b_ii_dont_fold_to_ptrue_increment_overflow:
+define <vscale x 16 x i1> @whilels_b_ii_known_always_true() {
+; CHECK-LABEL: whilels_b_ii_known_always_true:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #-1 // =0xffffffff
-; CHECK-NEXT: whilels p0.b, wzr, w8
+; CHECK-NEXT: ptrue p0.b
; CHECK-NEXT: ret
- %out = call <vscale x 16 x i1> @llvm.aarch64.sve.whilels.nxv16i1.i32(i32 0, i32 4294967295)
+ %out = call <vscale x 16 x i1> @llvm.aarch64.sve.whilels.nxv16i1.i32(i32 4294967294, i32 4294967295)
ret <vscale x 16 x i1> %out
}
|
I'm not familiar enough with the LLVM code here to tell if this is a problem, but this transform is only valid if the NZCV output of WHILELE is unused, right? Otherwise it'd have to fold to PTRUES |
We don't expose the "S" instruction variants at this level but instead have a dedicated PTEST ISD node that we later try to combine into an instruction that also sets the flags. |
Review ping. |
When the second operand of an incrementing while instruction is the maximum value, comparisons that include equality can never fail.
When the second operand of an incrementing while instruction is the maximum value, comparisons that include equality can never fail.