Skip to content

Commit

Permalink
[CVP] Refactor processMinMaxIntrinsic to check non-strict predicate…
Browse files Browse the repository at this point in the history
… in both directions (#82596)

This patch uses `getConstantRangeAtUse` in `processMinMaxIntrinsic` to
address the comment
#82478 (comment).
After this patch we can reuse the range result in
#82478.
  • Loading branch information
dtcxzyw authored Feb 22, 2024
1 parent 4235e44 commit 3ef63a7
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 13 deletions.
26 changes: 17 additions & 9 deletions llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,15 +530,23 @@ static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) {
// See if this min/max intrinsic always picks it's one specific operand.
static bool processMinMaxIntrinsic(MinMaxIntrinsic *MM, LazyValueInfo *LVI) {
CmpInst::Predicate Pred = CmpInst::getNonStrictPredicate(MM->getPredicate());
LazyValueInfo::Tristate Result = LVI->getPredicateAt(
Pred, MM->getLHS(), MM->getRHS(), MM, /*UseBlockValue=*/true);
if (Result == LazyValueInfo::Unknown)
return false;

++NumMinMax;
MM->replaceAllUsesWith(MM->getOperand(!Result));
MM->eraseFromParent();
return true;
ConstantRange LHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(0),
/*UndefAllowed*/ false);
ConstantRange RHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(1),
/*UndefAllowed*/ false);
if (LHS_CR.icmp(Pred, RHS_CR)) {
++NumMinMax;
MM->replaceAllUsesWith(MM->getLHS());
MM->eraseFromParent();
return true;
}
if (RHS_CR.icmp(Pred, LHS_CR)) {
++NumMinMax;
MM->replaceAllUsesWith(MM->getRHS());
MM->eraseFromParent();
return true;
}
return false;
}

// Rewrite this with.overflow intrinsic as non-overflowing.
Expand Down
63 changes: 59 additions & 4 deletions llvm/test/Transforms/CorrelatedValuePropagation/min-max.ll
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ define i8 @test6(i8 %x) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
; CHECK-NEXT: ret i8 42
;
%lim = icmp uge i8 %x, 42
Expand Down Expand Up @@ -119,7 +118,6 @@ define i8 @test10(i8 %x) {
; CHECK-LABEL: @test10(
; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
; CHECK-NEXT: ret i8 42
;
%lim = icmp ule i8 %x, 42
Expand Down Expand Up @@ -167,7 +165,6 @@ define i8 @test14(i8 %x) {
; CHECK-LABEL: @test14(
; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)
; CHECK-NEXT: ret i8 42
;
%lim = icmp sge i8 %x, 42
Expand Down Expand Up @@ -215,7 +212,6 @@ define i8 @test18(i8 %x) {
; CHECK-LABEL: @test18(
; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42)
; CHECK-NEXT: ret i8 42
;
%lim = icmp sle i8 %x, 42
Expand All @@ -235,3 +231,62 @@ define i8 @test19(i8 %x) {
%r = call i8 @llvm.smax(i8 %x, i8 42)
ret i8 %r
}

declare void @body(i32)

define void @test_bidirectional() {
; CHECK-LABEL: @test_bidirectional(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
; CHECK-NEXT: call void @body(i32 65535)
; CHECK-NEXT: [[INC]] = add nsw i32 [[INDVAR]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INDVAR]], 65535
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
entry:
br label %for.body

for.body:
%indvar = phi i32 [ 0, %entry ], [ %inc, %for.body ]
%smax = call i32 @llvm.smax.i32(i32 %indvar, i32 65535)
call void @body(i32 %smax)
%inc = add nsw i32 %indvar, 1
%cmp = icmp slt i32 %indvar, 65535
br i1 %cmp, label %for.body, label %exit

exit:
ret void
}

define i64 @test_at_use(i1 %cond, i64 %x) {
; CHECK-LABEL: @test_at_use(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[IF_END:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[X:%.*]], 0
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
; CHECK: if.then:
; CHECK-NEXT: ret i64 0
; CHECK: if.end:
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[X]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: ret i64 [[PHI]]
;
entry:
br i1 %cond, label %bb1, label %if.end

bb1:
%val = call i64 @llvm.smax.i64(i64 %x, i64 -1)
%cmp = icmp slt i64 %x, 0
br i1 %cmp, label %if.then, label %if.end

if.then:
ret i64 0

if.end:
%phi = phi i64 [%val, %bb1], [0, %entry]
ret i64 %phi
}

0 comments on commit 3ef63a7

Please sign in to comment.