Skip to content

Commit c752bb9

Browse files
authored
[IndVars] Strengthen inference of samesign flags (#170363)
When reviewing another change, I noticed that we were failing to infer samsign for two cases: 1) an unsigned comparison, and 2) when both arguments were known negative. Using CVP and InstCombine as a reference, we need to be careful to not allow eq/ne comparisons. I'm a bit unclear on the why of that, and for now am going with the low risk change. I may return to investigate that in a follow up. Compile time results look like noise to me, see: https://llvm-compile-time-tracker.com/compare.php?from=49a978712893fcf9e5f40ac488315d029cf15d3d&to=2ddb263604fd7d538e09dc1f805ebc30eb3ffab0&stat=instructions:u
1 parent ec6a15f commit c752bb9

36 files changed

+114
-115
lines changed

llvm/lib/Transforms/Utils/SimplifyIndVar.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,15 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp,
277277
LLVM_DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n');
278278
} else if (makeIVComparisonInvariant(ICmp, IVOperand)) {
279279
// fallthrough to end of function
280-
} else if (ICmpInst::isSigned(OriginalPred) &&
281-
SE->isKnownNonNegative(S) && SE->isKnownNonNegative(X)) {
282-
// If we were unable to make anything above, all we can is to canonicalize
283-
// the comparison hoping that it will open the doors for other
284-
// optimizations. If we find out that we compare two non-negative values,
285-
// we turn the instruction's predicate to its unsigned version. Note that
286-
// we cannot rely on Pred here unless we check if we have swapped it.
280+
} else if ((ICmpInst::isSigned(OriginalPred) ||
281+
(ICmpInst::isUnsigned(OriginalPred) && !ICmp->hasSameSign())) &&
282+
SE->haveSameSign(S, X)) {
283+
// Set the samesign flag on the compare if legal, and canonicalize to
284+
// the unsigned variant (for signed compares) hoping that it will open
285+
// the doors for other optimizations. Note that we cannot rely on Pred
286+
// here unless we check if we have swapped it.
287287
assert(ICmp->getPredicate() == OriginalPred && "Predicate changed?");
288-
LLVM_DEBUG(dbgs() << "INDVARS: Turn to unsigned comparison: " << *ICmp
288+
LLVM_DEBUG(dbgs() << "INDVARS: Marking comparison samesign: " << *ICmp
289289
<< '\n');
290290
ICmp->setPredicate(ICmpInst::getUnsignedPredicate(OriginalPred));
291291
ICmp->setSameSign();

llvm/test/Analysis/ScalarEvolution/pr44605.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ define i32 @test() {
2121
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 [[TMP0]], [[LOCAL_3_4]]
2222
; CHECK-NEXT: [[TMP2]] = add i32 [[TMP1]], [[LOCAL_3_31]]
2323
; CHECK-NEXT: [[TMP3]] = add nuw nsw i32 [[LOCAL_7_3]], 1
24-
; CHECK-NEXT: [[TMP4:%.*]] = icmp ugt i32 [[LOCAL_7_3]], 4
24+
; CHECK-NEXT: [[TMP4:%.*]] = icmp samesign ugt i32 [[LOCAL_7_3]], 4
2525
; CHECK-NEXT: br i1 [[TMP4]], label [[LATCH]], label [[INNER]]
2626
; CHECK: latch:
2727
; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32 [ [[TMP2]], [[INNER]] ]
2828
; CHECK-NEXT: [[TMP5]] = add nuw nsw i32 [[LOCAL_6_6]], 1
29-
; CHECK-NEXT: [[TMP6:%.*]] = icmp ugt i32 [[LOCAL_6_6]], 276
29+
; CHECK-NEXT: [[TMP6:%.*]] = icmp samesign ugt i32 [[LOCAL_6_6]], 276
3030
; CHECK-NEXT: br i1 [[TMP6]], label [[RETURN:%.*]], label [[OUTER]]
3131
; CHECK: return:
3232
; CHECK-NEXT: [[DOTLCSSA_LCSSA:%.*]] = phi i32 [ [[DOTLCSSA]], [[LATCH]] ]

llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,7 @@ define i32 @test4(i32 %a) {
237237
; CHECK-NEXT: [[CONV3:%.*]] = trunc i32 [[OR]] to i8
238238
; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i8 signext [[CONV3]])
239239
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i32 [[INDVARS_IV]], -1
240-
; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw i32 [[INDVARS_IV_NEXT]] to i8
241-
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[TMP0]], -14
240+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[INDVARS_IV_NEXT]], 242
242241
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
243242
; CHECK: for.end:
244243
; CHECK-NEXT: ret i32 0

llvm/test/Transforms/IndVarSimplify/ARM/code-size.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ define i32 @different_ivs(ptr %array, i32 %length, i32 %n) #0 {
749749
; CHECK-V8M-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
750750
; CHECK-V8M-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
751751
; CHECK-V8M-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
752-
; CHECK-V8M-NEXT: [[CONTINUE:%.*]] = icmp ult i64 [[I_NEXT]], [[N64]]
752+
; CHECK-V8M-NEXT: [[CONTINUE:%.*]] = icmp samesign ult i64 [[I_NEXT]], [[N64]]
753753
; CHECK-V8M-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
754754
; CHECK-V8M: exit:
755755
; CHECK-V8M-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
@@ -778,7 +778,7 @@ define i32 @different_ivs(ptr %array, i32 %length, i32 %n) #0 {
778778
; CHECK-V8A-NEXT: [[ARRAY_I:%.*]] = load i32, ptr [[ARRAY_I_PTR]], align 4
779779
; CHECK-V8A-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
780780
; CHECK-V8A-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
781-
; CHECK-V8A-NEXT: [[CONTINUE:%.*]] = icmp ult i64 [[I_NEXT]], [[N64]]
781+
; CHECK-V8A-NEXT: [[CONTINUE:%.*]] = icmp samesign ult i64 [[I_NEXT]], [[N64]]
782782
; CHECK-V8A-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
783783
; CHECK-V8A: exit:
784784
; CHECK-V8A-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]

llvm/test/Transforms/IndVarSimplify/ARM/indvar-unroll-imm-cost.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ define dso_local arm_aapcscc void @test(ptr nocapture %pDest, ptr nocapture read
6060
; CHECK-NEXT: [[ADD_PTR23]] = getelementptr inbounds i16, ptr [[PSRCB_ADDR_173]], i32 4
6161
; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, ptr [[PDEST_ADDR_175]], i32 1
6262
; CHECK-NEXT: [[ADD24]] = add nuw nsw i32 [[J_076]], 4
63-
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[ADD24]], [[TMP0]]
63+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[ADD24]], [[TMP0]]
6464
; CHECK-NEXT: br i1 [[CMP2]], label [[FOR_BODY3]], label [[FOR_END_LOOPEXIT:%.*]]
6565
; CHECK: for.end.loopexit:
6666
; CHECK-NEXT: [[ADD_PTR_LCSSA:%.*]] = phi ptr [ [[ADD_PTR]], [[FOR_BODY3]] ]

llvm/test/Transforms/IndVarSimplify/X86/eliminate-trunc.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ define void @test_08(i32 %n) {
414414
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
415415
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
416416
; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[IV]], [[SEXT]]
417-
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IV]], [[ZEXT]]
417+
; CHECK-NEXT: [[TMP1:%.*]] = icmp samesign ult i64 [[IV]], [[ZEXT]]
418418
; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP0]], [[TMP1]]
419419
; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
420420
; CHECK: exit:
@@ -600,7 +600,7 @@ define void @test_13b(i32 %n) {
600600
; CHECK: loop:
601601
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
602602
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
603-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], 1024
603+
; CHECK-NEXT: [[TMP0:%.*]] = icmp samesign ult i64 [[IV]], 1024
604604
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
605605
; CHECK: exit:
606606
; CHECK-NEXT: ret void
@@ -625,7 +625,7 @@ define void @test_13c(i32 %n) {
625625
; CHECK: loop:
626626
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
627627
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 2
628-
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[IV]], 1024
628+
; CHECK-NEXT: [[TMP0:%.*]] = icmp samesign ult i64 [[IV]], 1024
629629
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT:%.*]]
630630
; CHECK: exit:
631631
; CHECK-NEXT: ret void

llvm/test/Transforms/IndVarSimplify/X86/pr59615.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ define void @test() {
1818
; CHECK: bb8:
1919
; CHECK-NEXT: [[VAR9:%.*]] = load atomic i32, ptr addrspace(1) poison unordered, align 8, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
2020
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[VAR9]] to i64
21-
; CHECK-NEXT: [[VAR10:%.*]] = icmp ult i64 [[INDVARS_IV]], [[TMP0]]
21+
; CHECK-NEXT: [[VAR10:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], [[TMP0]]
2222
; CHECK-NEXT: br i1 [[VAR10]], label [[BB12]], label [[BB11:%.*]]
2323
; CHECK: bb11:
2424
; CHECK-NEXT: ret void

llvm/test/Transforms/IndVarSimplify/backedge-on-min-max.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ define void @min.unsigned.3(ptr %a, i32 %n) {
535535
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
536536
; CHECK-NEXT: br label [[LATCH]]
537537
; CHECK: latch:
538-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
538+
; CHECK-NEXT: [[BE_COND:%.*]] = icmp samesign ult i32 [[IDX_INC]], [[UMIN]]
539539
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
540540
; CHECK: exit.loopexit:
541541
; CHECK-NEXT: br label [[EXIT]]
@@ -586,7 +586,7 @@ define void @min.unsigned.4(ptr %a, i32 %n) {
586586
; CHECK-NEXT: store i32 [[IDX]], ptr [[ADDR]], align 4
587587
; CHECK-NEXT: br label [[LATCH]]
588588
; CHECK: latch:
589-
; CHECK-NEXT: [[BE_COND:%.*]] = icmp ult i32 [[IDX_INC]], [[UMIN]]
589+
; CHECK-NEXT: [[BE_COND:%.*]] = icmp samesign ult i32 [[IDX_INC]], [[UMIN]]
590590
; CHECK-NEXT: br i1 [[BE_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
591591
; CHECK: exit.loopexit:
592592
; CHECK-NEXT: br label [[EXIT]]

llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ define i32 @test_01(i32 %a, i32 %b, ptr %p) {
2121
; CHECK-NEXT: store i32 [[A:%.*]], ptr [[P]], align 4
2222
; CHECK-NEXT: br label [[MERGE]]
2323
; CHECK: merge:
24-
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[IV]], 100
24+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ult i32 [[IV]], 100
2525
; CHECK-NEXT: br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]]
2626
; CHECK: b3:
2727
; CHECK-NEXT: store i32 [[IV]], ptr [[P]], align 4
@@ -89,7 +89,7 @@ define i32 @test_02(i32 %a, i32 %b, ptr %p) {
8989
; CHECK-NEXT: store i32 [[A:%.*]], ptr [[P]], align 4
9090
; CHECK-NEXT: br label [[MERGE]]
9191
; CHECK: merge:
92-
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 100, [[IV]]
92+
; CHECK-NEXT: [[CMP2:%.*]] = icmp samesign ugt i32 100, [[IV]]
9393
; CHECK-NEXT: br i1 [[CMP2]], label [[B3:%.*]], label [[B4:%.*]]
9494
; CHECK: b3:
9595
; CHECK-NEXT: store i32 [[IV]], ptr [[P]], align 4

llvm/test/Transforms/IndVarSimplify/constant_result.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ define i16 @foo() {
1212
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [400 x i16], ptr @Y, i16 0, i16 [[I]]
1313
; CHECK-NEXT: store i16 0, ptr [[ARRAYIDX]], align 1
1414
; CHECK-NEXT: [[INC]] = add nuw nsw i16 [[I]], 1
15-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i16 [[INC]], 400
15+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i16 [[INC]], 400
1616
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
1717
; CHECK: for.end:
1818
; CHECK-NEXT: ret i16 400

0 commit comments

Comments
 (0)