Skip to content

Commit b8986ff

Browse files
committed
[CVP]: Fold icmp eq X, C to trunc X to i1 if C=2k+1 and X in [2k, 2k+1]
1 parent d4766bd commit b8986ff

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,39 @@ static bool constantFoldCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
332332
return true;
333333
}
334334

335+
/// Given an icmp `icmp eq X, C`,
336+
/// if we already know that C is 2k+1 and X is in [2k, 2k+1],
337+
/// then we can fold it to `trunc X to i1`.
338+
static bool processEqualityICmp(CmpInst *Cmp, LazyValueInfo *LVI) {
339+
if (Cmp->getType()->isVectorTy() ||
340+
!Cmp->getOperand(0)->getType()->isIntegerTy() || !Cmp->isEquality())
341+
return false;
342+
343+
Value *Op0 = Cmp->getOperand(0);
344+
Value *Op1 = Cmp->getOperand(1);
345+
ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
346+
if (!CI)
347+
return false;
348+
349+
ConstantRange Range =
350+
LVI->getConstantRangeAtUse(Cmp->getOperandUse(0), /*UndefAllowed*/ true);
351+
APInt RangeSize = Range.getUpper() - Range.getLower();
352+
APInt Value = CI->getValue();
353+
if (RangeSize != 2 || !Range.contains(Value))
354+
return false;
355+
356+
bool ShouldBeOdd = Cmp->getPredicate() == ICmpInst::Predicate::ICMP_EQ;
357+
if ((CI->getValue() & 1) == ShouldBeOdd) {
358+
IRBuilder<> B{Cmp};
359+
auto *Trunc = B.CreateTruncOrBitCast(Op0, Cmp->getType());
360+
Cmp->replaceAllUsesWith(Trunc);
361+
Cmp->eraseFromParent();
362+
return true;
363+
}
364+
365+
return false;
366+
}
367+
335368
static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
336369
if (constantFoldCmp(Cmp, LVI))
337370
return true;
@@ -340,6 +373,9 @@ static bool processCmp(CmpInst *Cmp, LazyValueInfo *LVI) {
340373
if (processICmp(ICmp, LVI))
341374
return true;
342375

376+
if (processEqualityICmp(Cmp, LVI))
377+
return true;
378+
343379
return false;
344380
}
345381

llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -614,10 +614,10 @@ define void @test_cmp_phi(i8 %a) {
614614
; CHECK-NEXT: br i1 [[C0]], label [[LOOP:%.*]], label [[EXIT:%.*]]
615615
; CHECK: loop:
616616
; CHECK-NEXT: [[P:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B:%.*]], [[LOOP]] ]
617-
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[P]], 0
617+
; CHECK-NEXT: [[TMP0:%.*]] = trunc i8 [[P]] to i1
618618
; CHECK-NEXT: [[C4:%.*]] = call i1 @get_bool()
619619
; CHECK-NEXT: [[B]] = zext i1 [[C4]] to i8
620-
; CHECK-NEXT: br i1 [[C1]], label [[LOOP]], label [[EXIT]]
620+
; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[EXIT]]
621621
; CHECK: exit:
622622
; CHECK-NEXT: ret void
623623
;
@@ -1484,7 +1484,7 @@ define i1 @test_icmp_eq_on_valid_bool_range(i8 %x) {
14841484
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
14851485
; CHECK-NEXT: br label [[BB3:%.*]]
14861486
; CHECK: bb1:
1487-
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[X]], 1
1487+
; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
14881488
; CHECK-NEXT: br label [[BB3]]
14891489
; CHECK: bb3:
14901490
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
@@ -1514,7 +1514,7 @@ define i1 @test_icmp_ne_on_valid_bool_range(i8 %x) {
15141514
; CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @get_bool()
15151515
; CHECK-NEXT: br label [[BB3:%.*]]
15161516
; CHECK: bb1:
1517-
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[X]], 0
1517+
; CHECK-NEXT: [[TMP3:%.*]] = trunc i8 [[X]] to i1
15181518
; CHECK-NEXT: br label [[BB3]]
15191519
; CHECK: bb3:
15201520
; CHECK-NEXT: [[TMP4:%.*]] = phi i1 [ [[TMP3]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]

llvm/test/Transforms/JumpThreading/pr33917.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ define void @patatino() personality ptr @rust_eh_personality {
1515
; CHECK-LABEL: @patatino(
1616
; CHECK-NEXT: bb9:
1717
; CHECK-NEXT: [[T9:%.*]] = invoke ptr @foo()
18-
; CHECK-NEXT: to label [[GOOD:%.*]] unwind label [[BAD:%.*]]
18+
; CHECK-NEXT: to label [[GOOD:%.*]] unwind label [[BAD:%.*]]
1919
; CHECK: bad:
2020
; CHECK-NEXT: [[T10:%.*]] = landingpad { ptr, i32 }
21-
; CHECK-NEXT: cleanup
21+
; CHECK-NEXT: cleanup
2222
; CHECK-NEXT: resume { ptr, i32 } [[T10]]
2323
; CHECK: good:
2424
; CHECK-NEXT: [[T11:%.*]] = icmp ne ptr [[T9]], null
2525
; CHECK-NEXT: [[T12:%.*]] = zext i1 [[T11]] to i64
26-
; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[T12]], 1
27-
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[DONE:%.*]]
26+
; CHECK-NEXT: [[TMP0:%.*]] = trunc i64 [[T12]] to i1
27+
; CHECK-NEXT: br i1 [[TMP0]], label [[IF_TRUE:%.*]], label [[DONE:%.*]]
2828
; CHECK: if_true:
2929
; CHECK-NEXT: call void @llvm.assume(i1 [[T11]])
3030
; CHECK-NEXT: br label [[DONE]]

0 commit comments

Comments
 (0)