-
Notifications
You must be signed in to change notification settings - Fork 14.3k
SimplifyIndVar: teach widenLoopCompare about samesign #125851
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
SimplifyIndVar: teach widenLoopCompare about samesign #125851
Conversation
There is still some way to go to optimize optimally with samesign.
Duplicate of #125764, since GitHub seems to have hung on that PR. |
@llvm/pr-subscribers-llvm-transforms Author: Ramkumar Ramachandra (artagnon) ChangesProof: https://alive2.llvm.org/ce/z/NVXaeo Patch is 37.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125851.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index e41a1adadfcc5bd..7b9c5c77cbe986e 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -1614,7 +1614,8 @@ bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
// (A) == icmp slt i32 sext(%narrow), sext(%val)
// == icmp slt i32 zext(%narrow), sext(%val)
bool IsSigned = getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
- if (!(DU.NeverNegative || IsSigned == Cmp->isSigned()))
+ bool CmpPreferredSign = Cmp->hasSameSign() ? IsSigned : Cmp->isSigned();
+ if (!DU.NeverNegative && IsSigned != CmpPreferredSign)
return false;
Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
@@ -1627,7 +1628,7 @@ bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
// Widen the other operand of the compare, if necessary.
if (CastWidth < IVWidth) {
- Value *ExtOp = createExtendInst(Op, WideType, Cmp->isSigned(), Cmp);
+ Value *ExtOp = createExtendInst(Op, WideType, CmpPreferredSign, Cmp);
DU.NarrowUse->replaceUsesOfWith(Op, ExtOp);
}
return true;
diff --git a/llvm/test/Transforms/IndVarSimplify/iv-ext-samesign.ll b/llvm/test/Transforms/IndVarSimplify/iv-ext-samesign.ll
new file mode 100644
index 000000000000000..1207f47c5e3c90c
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/iv-ext-samesign.ll
@@ -0,0 +1,716 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=indvars -S | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+define i32 @iv_zext_zext_sgt_slt(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_sgt_slt(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[ITER_COUNT]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT2:%.*]] = add i32 [[INDVARS_IV1:%.*]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1]] = phi i32 [ [[INDVARS_IV_NEXT2]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ [[IV_OUTER_1:%.*]], %[[PH]] ], [ [[ITER_COUNT]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER_1]] = add nsw i32 [[IV_OUTER]], -1
+; CHECK-NEXT: [[EXT_OUTER:%.*]] = zext nneg i32 [[IV_OUTER_1]] to i64
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[EXT_OUTER]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp sgt i32 [[IV_OUTER]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp sgt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_zext_zext_gt_slt(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_gt_slt(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_zext_zext_gt_slt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_gt_slt_exitlimit(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], i32 [[EXIT_LIMIT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[EXIT_LIMIT]] to i64
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], [[TMP1]]
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
+; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp samesign ugt i32 %iv.outer, %exit.limit
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_zext_zext_sgt_lt(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_sgt_lt(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[ITER_COUNT]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT2:%.*]] = add i32 [[INDVARS_IV1:%.*]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1]] = phi i32 [ [[INDVARS_IV_NEXT2]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ [[IV_OUTER_1:%.*]], %[[PH]] ], [ [[ITER_COUNT]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER_1]] = add nsw i32 [[IV_OUTER]], -1
+; CHECK-NEXT: [[EXT_OUTER:%.*]] = zext nneg i32 [[IV_OUTER_1]] to i64
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[EXT_OUTER]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp sgt i32 [[IV_OUTER]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp sgt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp samesign ult i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_zext_zext_sgt_lt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_sgt_lt_exitlimit(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], i32 [[EXIT_LIMIT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ [[IV_OUTER_1:%.*]], %[[PH]] ], [ [[ITER_COUNT]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER_1]] = add nsw i32 [[IV_OUTER]], -1
+; CHECK-NEXT: [[EXT_OUTER:%.*]] = zext nneg i32 [[IV_OUTER_1]] to i64
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[EXT_OUTER]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp sgt i32 [[IV_OUTER]], [[EXIT_LIMIT]]
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[IV_OUTER_1]] to i64
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp samesign ult i64 [[INDVARS_IV_NEXT]], [[TMP1]]
+; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp sgt i32 %iv.outer, %exit.limit
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp samesign ult i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_zext_zext_gt_lt(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_zext_zext_gt_lt(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[ITER_COUNT]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT2:%.*]] = add i32 [[INDVARS_IV1:%.*]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV1]] = phi i32 [ [[INDVARS_IV_NEXT2]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER:%.*]] = phi i32 [ [[IV_OUTER_1:%.*]], %[[PH]] ], [ [[ITER_COUNT]], %[[ENTRY]] ]
+; CHECK-NEXT: [[IV_OUTER_1]] = add nsw i32 [[IV_OUTER]], -1
+; CHECK-NEXT: [[EXT_OUTER:%.*]] = zext nneg i32 [[IV_OUTER_1]] to i64
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[EXT_OUTER]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[IV_OUTER]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = zext nneg i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i8, ptr %ptr, i64 %ext.outer
+ store i8 0, ptr %gep.outer
+ %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
+ br i1 %exit.cond.outer, label %inner.loop, label %ph
+
+inner.loop:
+ %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
+ %ext.inner = zext nneg i32 %iv.inner to i64
+ %gep.inner = getelementptr i8, ptr %ptr, i64 %ext.inner
+ store i8 0, ptr %gep.inner
+ %iv.next = add nuw nsw i32 %iv.inner, 1
+ %exit.cond.inner = icmp samesign ult i32 %iv.next, %iv.outer.1
+ br i1 %exit.cond.inner, label %inner.loop, label %ph
+
+exit:
+ ret i32 0
+}
+
+define i32 @iv_sext_sext_sgt_slt(i32 %iter.count, ptr %ptr) {
+; CHECK-LABEL: define i32 @iv_sext_sext_sgt_slt(
+; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add nsw i32 [[ITER_COUNT]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[ITER_COUNT]] to i64
+; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
+; CHECK: [[PH_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[PH:.*]]
+; CHECK: [[PH]]:
+; CHECK-NEXT: [[INDVARS_IV_NEXT2:%.*]] = add i32 [[INDVARS_IV1:%.*]], -1
+; CHECK-NEXT: br label %[[OUTER_LOOP]]
+; CHECK: [[OUTER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV3:%.*]] = phi i64 [ [[INDVARS_IV_NEXT4:%.*]], %[[PH]] ], [ [[TMP1]], %[[ENTRY]] ]
+; CHECK-NEXT: [[INDVARS_IV1]] = phi i32 [ [[INDVARS_IV_NEXT2]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: [[INDVARS_IV_NEXT4]] = add nsw i64 [[INDVARS_IV3]], -1
+; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV_NEXT4]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_OUTER]], align 1
+; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp sgt i64 [[INDVARS_IV3]], 1
+; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
+; CHECK: [[INNER_LOOP_PREHEADER]]:
+; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64
+; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
+; CHECK: [[INNER_LOOP]]:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
+; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDVARS_IV]]
+; CHECK-NEXT: store i8 0, ptr [[GEP_INNER]], align 1
+; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
+; CHECK: [[EXIT:.*:]]
+; CHECK-NEXT: ret i32 0
+;
+entry:
+ br label %outer.loop
+
+ph:
+ br label %outer.loop
+
+outer.loop:
+ %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
+ %iv.outer.1 = add nsw i32 %iv.outer, -1
+ %ext.outer = sext i32 %iv.outer.1 to i64
+ %gep.outer = getelementptr i...
[truncated]
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/11368 Here is the relevant piece of the build log for the reference
|
Proof: https://alive2.llvm.org/ce/z/NVXaeo