Skip to content

Commit 7cf499c

Browse files
authored
[ConstraintElim] Check if second op implies first for And. (llvm#75750)
Generalize checkAndSecondOpImpliedByFirst to also check if the second operand implies the first.
1 parent c37734d commit 7cf499c

File tree

5 files changed

+37
-25
lines changed

5 files changed

+37
-25
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

+27-15
Original file line numberDiff line numberDiff line change
@@ -1365,16 +1365,27 @@ removeEntryFromStack(const StackEntry &E, ConstraintInfo &Info,
13651365
ReproducerCondStack.pop_back();
13661366
}
13671367

1368-
/// Check if the first condition for an AND implies the second.
1369-
static bool checkAndSecondOpImpliedByFirst(
1370-
FactOrCheck &CB, ConstraintInfo &Info, Module *ReproducerModule,
1371-
SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1372-
SmallVectorImpl<StackEntry> &DFSInStack) {
1368+
/// Check if either the first condition of an AND is implied by the second or
1369+
/// vice versa.
1370+
static bool
1371+
checkAndOpImpliedByOther(FactOrCheck &CB, ConstraintInfo &Info,
1372+
Module *ReproducerModule,
1373+
SmallVectorImpl<ReproducerEntry> &ReproducerCondStack,
1374+
SmallVectorImpl<StackEntry> &DFSInStack) {
13731375

13741376
CmpInst::Predicate Pred;
13751377
Value *A, *B;
13761378
Instruction *And = CB.getContextInst();
1377-
if (!match(And->getOperand(0), m_ICmp(Pred, m_Value(A), m_Value(B))))
1379+
CmpInst *CmpToCheck = cast<CmpInst>(CB.getInstructionToSimplify());
1380+
unsigned OtherOpIdx = And->getOperand(0) == CmpToCheck ? 1 : 0;
1381+
1382+
// Don't try to simplify the first condition of a select by the second, as
1383+
// this may make the select more poisonous than the original one.
1384+
// TODO: check if the first operand may be poison.
1385+
if (OtherOpIdx != 0 && isa<SelectInst>(And))
1386+
return false;
1387+
1388+
if (!match(And->getOperand(OtherOpIdx), m_ICmp(Pred, m_Value(A), m_Value(B))))
13781389
return false;
13791390

13801391
// Optimistically add fact from first condition.
@@ -1385,11 +1396,12 @@ static bool checkAndSecondOpImpliedByFirst(
13851396

13861397
bool Changed = false;
13871398
// Check if the second condition can be simplified now.
1388-
ICmpInst *Cmp = cast<ICmpInst>(And->getOperand(1));
1389-
if (auto ImpliedCondition = checkCondition(
1390-
Cmp->getPredicate(), Cmp->getOperand(0), Cmp->getOperand(1), Cmp,
1391-
Info, CB.NumIn, CB.NumOut, CB.getContextInst())) {
1392-
And->setOperand(1, ConstantInt::getBool(And->getType(), *ImpliedCondition));
1399+
if (auto ImpliedCondition =
1400+
checkCondition(CmpToCheck->getPredicate(), CmpToCheck->getOperand(0),
1401+
CmpToCheck->getOperand(1), CmpToCheck, Info, CB.NumIn,
1402+
CB.NumOut, CB.getContextInst())) {
1403+
And->setOperand(1 - OtherOpIdx,
1404+
ConstantInt::getBool(And->getType(), *ImpliedCondition));
13931405
Changed = true;
13941406
}
13951407

@@ -1609,11 +1621,11 @@ static bool eliminateConstraints(Function &F, DominatorTree &DT, LoopInfo &LI,
16091621
bool Simplified = checkAndReplaceCondition(
16101622
Cmp, Info, CB.NumIn, CB.NumOut, CB.getContextInst(),
16111623
ReproducerModule.get(), ReproducerCondStack, S.DT, ToRemove);
1612-
if (!Simplified && match(CB.getContextInst(),
1613-
m_LogicalAnd(m_Value(), m_Specific(Inst)))) {
1624+
if (!Simplified &&
1625+
match(CB.getContextInst(), m_LogicalAnd(m_Value(), m_Value()))) {
16141626
Simplified =
1615-
checkAndSecondOpImpliedByFirst(CB, Info, ReproducerModule.get(),
1616-
ReproducerCondStack, DFSInStack);
1627+
checkAndOpImpliedByOther(CB, Info, ReproducerModule.get(),
1628+
ReproducerCondStack, DFSInStack);
16171629
}
16181630
Changed |= Simplified;
16191631
}

llvm/test/Transforms/ConstraintElimination/and-implied-by-operands.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ define i1 @test_first_and_condition_implied_by_second_ops(i8 %x) {
3131
; CHECK-NEXT: entry:
3232
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
3333
; CHECK-NEXT: [[T_1:%.*]] = icmp ugt i8 [[X]], 5
34-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[T_1]], [[C_1]]
34+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]]
3535
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
3636
; CHECK: then:
3737
; CHECK-NEXT: ret i1 false
@@ -105,7 +105,7 @@ define i1 @test_same_cond_for_and(i8 %x) {
105105
; CHECK-LABEL: @test_same_cond_for_and(
106106
; CHECK-NEXT: entry:
107107
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
108-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_1]], true
108+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]]
109109
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
110110
; CHECK: then:
111111
; CHECK-NEXT: ret i1 false
@@ -128,7 +128,7 @@ define i1 @test_same_cond_for_and_select_form(i8 %x) {
128128
; CHECK-LABEL: @test_same_cond_for_and_select_form(
129129
; CHECK-NEXT: entry:
130130
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
131-
; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 true, i1 false
131+
; CHECK-NEXT: [[AND:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false
132132
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
133133
; CHECK: then:
134134
; CHECK-NEXT: ret i1 false
@@ -152,7 +152,7 @@ define i1 @test_second_and_condition_not_implied_by_first(i8 %x) {
152152
; CHECK-NEXT: entry:
153153
; CHECK-NEXT: [[C_1:%.*]] = icmp ugt i8 [[X:%.*]], 10
154154
; CHECK-NEXT: [[C_2:%.*]] = icmp ugt i8 [[X]], 5
155-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_2]], [[C_1]]
155+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[C_1]]
156156
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
157157
; CHECK: then:
158158
; CHECK-NEXT: ret i1 false

llvm/test/Transforms/ConstraintElimination/and.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ define i1 @test_and_chain_select_ule(i4 %x, i4 %y, i4 %z, i4 %a) {
438438
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]
439439
; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 3, [[X]]
440440
; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 3, [[A:%.*]]
441-
; CHECK-NEXT: [[AND_1:%.*]] = select i1 [[C_1]], i1 true, i1 false
441+
; CHECK-NEXT: [[AND_1:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false
442442
; CHECK-NEXT: [[AND_2:%.*]] = select i1 [[AND_1]], i1 [[C_3]], i1 false
443443
; CHECK-NEXT: [[AND_3:%.*]] = select i1 [[C_4]], i1 [[AND_2]], i1 false
444444
; CHECK-NEXT: br i1 [[AND_3]], label [[BB1:%.*]], label [[EXIT:%.*]]
@@ -522,7 +522,7 @@ define i1 @test_and_chain_select_ule_logical_or(i4 %x, i4 %y, i4 %z, i4 %a) {
522522
; CHECK-NEXT: [[C_2:%.*]] = icmp ule i4 [[Y]], [[Z:%.*]]
523523
; CHECK-NEXT: [[C_3:%.*]] = icmp ule i4 3, [[X]]
524524
; CHECK-NEXT: [[C_4:%.*]] = icmp ule i4 3, [[A:%.*]]
525-
; CHECK-NEXT: [[AND_1:%.*]] = select i1 [[C_1]], i1 true, i1 false
525+
; CHECK-NEXT: [[AND_1:%.*]] = select i1 [[C_1]], i1 [[C_1]], i1 false
526526
; CHECK-NEXT: [[AND_2:%.*]] = select i1 [[AND_1]], i1 [[C_3]], i1 false
527527
; CHECK-NEXT: [[AND_3:%.*]] = select i1 [[C_4]], i1 [[AND_2]], i1 false
528528
; CHECK-NEXT: [[AND_4:%.*]] = select i1 [[AND_3]], i1 true, i1 false

llvm/test/Transforms/ConstraintElimination/gep-arithmetic-signed-predicates.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ define i4 @ptr_N_signed_positive_assume(ptr %src, ptr %lower, ptr %upper, i16 %N
611611
; CHECK: step.check:
612612
; CHECK-NEXT: [[STEP_POS:%.*]] = icmp sge i16 [[STEP:%.*]], 0
613613
; CHECK-NEXT: [[STEP_SLT_N:%.*]] = icmp slt i16 [[STEP]], [[N]]
614-
; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 [[STEP_POS]], false
614+
; CHECK-NEXT: [[AND_STEP:%.*]] = and i1 false, [[STEP_SLT_N]]
615615
; CHECK-NEXT: br i1 [[AND_STEP]], label [[PTR_CHECK:%.*]], label [[EXIT:%.*]]
616616
; CHECK: ptr.check:
617617
; CHECK-NEXT: [[SRC_STEP:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i16 [[STEP]]

llvm/test/Transforms/ConstraintElimination/geps-precondition-overflow-check.ll

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ define i1 @overflow_check_2_and(ptr %dst) {
3636
; CHECK-NEXT: entry:
3737
; CHECK-NEXT: [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
3838
; CHECK-NEXT: [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
39-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[DST_5_UGE]], true
39+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
4040
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
4141
; CHECK: then:
4242
; CHECK-NEXT: [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
@@ -65,7 +65,7 @@ define i1 @overflow_check_3_and(ptr %dst) {
6565
; CHECK-NEXT: entry:
6666
; CHECK-NEXT: [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
6767
; CHECK-NEXT: [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
68-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[DST_5_UGE]], true
68+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
6969
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
7070
; CHECK: then:
7171
; CHECK-NEXT: [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4
@@ -98,7 +98,7 @@ define i1 @overflow_check_4_and(ptr %dst) {
9898
; CHECK-NEXT: entry:
9999
; CHECK-NEXT: [[DST_5:%.*]] = getelementptr i32, ptr [[DST:%.*]], i64 5
100100
; CHECK-NEXT: [[DST_5_UGE:%.*]] = icmp uge ptr [[DST_5]], [[DST]]
101-
; CHECK-NEXT: [[AND:%.*]] = and i1 [[DST_5_UGE]], true
101+
; CHECK-NEXT: [[AND:%.*]] = and i1 true, [[DST_5_UGE]]
102102
; CHECK-NEXT: br i1 [[AND]], label [[THEN:%.*]], label [[ELSE:%.*]]
103103
; CHECK: then:
104104
; CHECK-NEXT: [[DST_4:%.*]] = getelementptr i32, ptr [[DST]], i64 4

0 commit comments

Comments
 (0)