Skip to content

Commit a6e387e

Browse files
committed
SimplifyIndVar: teach widenLoopCompare about samesign
There is still some way to go to optimize optimally with samesign.
1 parent f999897 commit a6e387e

File tree

2 files changed

+11
-15
lines changed

2 files changed

+11
-15
lines changed

llvm/lib/Transforms/Utils/SimplifyIndVar.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,8 @@ bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
16141614
// (A) == icmp slt i32 sext(%narrow), sext(%val)
16151615
// == icmp slt i32 zext(%narrow), sext(%val)
16161616
bool IsSigned = getExtendKind(DU.NarrowDef) == ExtendKind::Sign;
1617-
if (!(DU.NeverNegative || IsSigned == Cmp->isSigned()))
1617+
bool CmpPreferredSign = Cmp->hasSameSign() ? IsSigned : Cmp->isSigned();
1618+
if (!DU.NeverNegative && IsSigned != CmpPreferredSign)
16181619
return false;
16191620

16201621
Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
@@ -1627,7 +1628,7 @@ bool WidenIV::widenLoopCompare(WidenIV::NarrowIVDefUse DU) {
16271628

16281629
// Widen the other operand of the compare, if necessary.
16291630
if (CastWidth < IVWidth) {
1630-
Value *ExtOp = createExtendInst(Op, WideType, Cmp->isSigned(), Cmp);
1631+
Value *ExtOp = createExtendInst(Op, WideType, CmpPreferredSign, Cmp);
16311632
DU.NarrowUse->replaceUsesOfWith(Op, ExtOp);
16321633
}
16331634
return true;

llvm/test/Transforms/IndVarSimplify/iv-ext-samesign.ll

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ define i32 @iv_zext_zext_gt_slt(i32 %iter.count, ptr %ptr) {
7979
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
8080
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
8181
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
82-
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
83-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
82+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], 1
8483
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
8584
; CHECK: [[INNER_LOOP_PREHEADER]]:
8685
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
@@ -127,6 +126,7 @@ define i32 @iv_zext_zext_gt_slt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr
127126
; CHECK-SAME: i32 [[ITER_COUNT:%.*]], i32 [[EXIT_LIMIT:%.*]], ptr [[PTR:%.*]]) {
128127
; CHECK-NEXT: [[ENTRY:.*]]:
129128
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
129+
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[EXIT_LIMIT]] to i64
130130
; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
131131
; CHECK: [[PH_LOOPEXIT:.*]]:
132132
; CHECK-NEXT: br label %[[PH:.*]]
@@ -137,8 +137,7 @@ define i32 @iv_zext_zext_gt_slt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr
137137
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
138138
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
139139
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
140-
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
141-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], [[EXIT_LIMIT]]
140+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], [[TMP1]]
142141
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
143142
; CHECK: [[INNER_LOOP_PREHEADER]]:
144143
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
@@ -436,8 +435,7 @@ define i32 @iv_sext_sext_gt_slt(i32 %iter.count, ptr %ptr) {
436435
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
437436
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
438437
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
439-
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
440-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
438+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], 1
441439
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
442440
; CHECK: [[INNER_LOOP_PREHEADER]]:
443441
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
@@ -484,6 +482,7 @@ define i32 @iv_sext_sext_gt_slt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr
484482
; CHECK-SAME: i32 [[ITER_COUNT:%.*]], i32 [[EXIT_LIMIT:%.*]], ptr [[PTR:%.*]]) {
485483
; CHECK-NEXT: [[ENTRY:.*]]:
486484
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
485+
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[EXIT_LIMIT]] to i64
487486
; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
488487
; CHECK: [[PH_LOOPEXIT:.*]]:
489488
; CHECK-NEXT: br label %[[PH:.*]]
@@ -494,8 +493,7 @@ define i32 @iv_sext_sext_gt_slt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr
494493
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
495494
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
496495
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
497-
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
498-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], [[EXIT_LIMIT]]
496+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV1]], [[TMP1]]
499497
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
500498
; CHECK: [[INNER_LOOP_PREHEADER]]:
501499
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
@@ -617,15 +615,13 @@ define i32 @iv_sext_sext_sgt_lt_exitlimit(i32 %iter.count, i32 %exit.limit, ptr
617615
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp sgt i64 [[INDVARS_IV1]], [[TMP4]]
618616
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
619617
; CHECK: [[INNER_LOOP_PREHEADER]]:
620-
; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT2]] to i32
621-
; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64
622618
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
623619
; CHECK: [[INNER_LOOP]]:
624620
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
625621
; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV]]
626622
; CHECK-NEXT: store double poison, ptr [[GEP_INNER]], align 8
627623
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
628-
; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp samesign ult i64 [[INDVARS_IV_NEXT]], [[TMP3]]
624+
; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp samesign ult i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
629625
; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
630626
; CHECK: [[EXIT:.*:]]
631627
; CHECK-NEXT: ret i32 0
@@ -676,8 +672,7 @@ define i32 @iv_sext_sext_gt_lt(i32 %iter.count, ptr %ptr) {
676672
; CHECK-NEXT: [[INDVARS_IV_NEXT4]] = add nsw i64 [[INDVARS_IV3]], -1
677673
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT4]]
678674
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
679-
; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV3]] to i32
680-
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP2]], 1
675+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i64 [[INDVARS_IV3]], 1
681676
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
682677
; CHECK: [[INNER_LOOP_PREHEADER]]:
683678
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[INDVARS_IV1]] to i64

0 commit comments

Comments
 (0)