Skip to content

Commit

Permalink
Revert "[LICM] Support logical AND/OR when hoisting min/max"
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalybuka committed Mar 10, 2023
1 parent eb8ebab commit f902ead
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 31 deletions.
16 changes: 1 addition & 15 deletions llvm/lib/Transforms/Scalar/LICM.cpp
Expand Up @@ -2416,19 +2416,11 @@ bool pointerInvalidatedByBlock(BasicBlock &BB, MemorySSA &MSSA, MemoryUse &MU) {
static bool hoistMinMax(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo,
MemorySSAUpdater &MSSAU) {
bool Inverse = false;
bool IsLogical = false;
using namespace PatternMatch;
Value *Cond1, *Cond2;
if (match(&I, m_Or(m_Value(Cond1), m_Value(Cond2))))
Inverse = true;
else if (match(&I, m_LogicalOr(m_Value(Cond1), m_Value(Cond2)))) {
Inverse = true;
IsLogical = true;
} else if (match(&I, m_And(m_Value(Cond1), m_Value(Cond2)))) {
// Do nothing
} else if (match(&I, m_LogicalAnd(m_Value(Cond1), m_Value(Cond2))))
IsLogical = true;
else
else if (!match(&I, m_And(m_Value(Cond1), m_Value(Cond2))))
return false;

auto MatchICmpAgainstInvariant = [&](Value *C, ICmpInst::Predicate &P,
Expand Down Expand Up @@ -2466,12 +2458,6 @@ static bool hoistMinMax(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo,
auto *Preheader = L.getLoopPreheader();
assert(Preheader && "Loop is not in simplify form?");
IRBuilder<> Builder(Preheader->getTerminator());
// We are about to create a new guaranteed use for RHS2 which might not exist
// before (if it was a non-taken input of logical and/or instruction). If it
// was poison, we need to freeze it. Note that no new use for LHS and RHS1 are
// introduced, so they don't need this.
if (IsLogical)
RHS2 = Builder.CreateFreeze(RHS2, RHS2->getName() + ".fr");
Value *NewRHS = Builder.CreateBinaryIntrinsic(
id, RHS1, RHS2, nullptr, StringRef("invariant.") +
(ICmpInst::isSigned(P1) ? "s" : "u") +
Expand Down
32 changes: 16 additions & 16 deletions llvm/test/Transforms/LICM/min_max.ll
Expand Up @@ -721,17 +721,17 @@ exit:
ret i32 %iv
}

; inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.
; TODO: inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.
; Counter-example: %cmp_1 = false, %inv_2 = poison.
define i32 @test_logical_and_ult_needs_freeze(i32 %start, i32 %inv_1, i32 %inv_2) {
; CHECK-LABEL: @test_logical_and_ult_needs_freeze(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]
; CHECK-NEXT: [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]
; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = select i1 [[CMP_1]], i1 [[CMP_2]], i1 false
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
Expand All @@ -753,17 +753,17 @@ exit:
ret i32 %iv
}

; turn to %iv <u umin(inv_1, inv_2) and hoist it out of loop.
; TODO: turn to %iv <u umin(inv_1, inv_2) and hoist it out of loop.
; https://alive2.llvm.org/ce/z/mhKGtT
define i32 @test_logical_and_ult_pos(i32 %start, i32 %inv_1, i32 noundef %inv_2) {
; CHECK-LABEL: @test_logical_and_ult_pos(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]
; CHECK-NEXT: [[INVARIANT_UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMIN]]
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]
; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = select i1 [[CMP_1]], i1 [[CMP_2]], i1 false
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
Expand All @@ -785,16 +785,16 @@ exit:
ret i32 %iv
}

; inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.
; TODO: inv_2 needs freeze because hoisted umax would create a new use that didn't exist before.
define i32 @test_logical_or_ult_inv_needs_freeze(i32 %start, i32 %inv_1, i32 %inv_2) {
; CHECK-LABEL: @test_logical_or_ult_inv_needs_freeze(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]
; CHECK-NEXT: [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMAX]]
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]
; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = select i1 [[CMP_1]], i1 true, i1 [[CMP_2]]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
Expand All @@ -816,17 +816,17 @@ exit:
ret i32 %iv
}

; turn to %iv <u umax(inv_1, inv_2) and hoist it out of loop.
; TODO: turn to %iv <u umax(inv_1, inv_2) and hoist it out of loop.
; https://alive2.llvm.org/ce/z/zgyG5N
define i32 @test_logical_or_ult_inv_pos(i32 %start, i32 %inv_1, i32 noundef %inv_2) {
; CHECK-LABEL: @test_logical_or_ult_inv_pos(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[INV_2_FR:%.*]] = freeze i32 [[INV_2:%.*]]
; CHECK-NEXT: [[INVARIANT_UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[INV_1:%.*]], i32 [[INV_2_FR]])
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV]], [[INVARIANT_UMAX]]
; CHECK-NEXT: [[CMP_1:%.*]] = icmp ult i32 [[IV]], [[INV_1:%.*]]
; CHECK-NEXT: [[CMP_2:%.*]] = icmp ult i32 [[IV]], [[INV_2:%.*]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = select i1 [[CMP_1]], i1 true, i1 [[CMP_2]]
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
Expand Down

0 comments on commit f902ead

Please sign in to comment.