Skip to content

Commit 3ef63a7

Browse files
authored
[CVP] Refactor processMinMaxIntrinsic to check non-strict predicate 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.
1 parent 4235e44 commit 3ef63a7

File tree

2 files changed

+76
-13
lines changed

2 files changed

+76
-13
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -530,15 +530,23 @@ static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) {
530530
// See if this min/max intrinsic always picks it's one specific operand.
531531
static bool processMinMaxIntrinsic(MinMaxIntrinsic *MM, LazyValueInfo *LVI) {
532532
CmpInst::Predicate Pred = CmpInst::getNonStrictPredicate(MM->getPredicate());
533-
LazyValueInfo::Tristate Result = LVI->getPredicateAt(
534-
Pred, MM->getLHS(), MM->getRHS(), MM, /*UseBlockValue=*/true);
535-
if (Result == LazyValueInfo::Unknown)
536-
return false;
537-
538-
++NumMinMax;
539-
MM->replaceAllUsesWith(MM->getOperand(!Result));
540-
MM->eraseFromParent();
541-
return true;
533+
ConstantRange LHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(0),
534+
/*UndefAllowed*/ false);
535+
ConstantRange RHS_CR = LVI->getConstantRangeAtUse(MM->getOperandUse(1),
536+
/*UndefAllowed*/ false);
537+
if (LHS_CR.icmp(Pred, RHS_CR)) {
538+
++NumMinMax;
539+
MM->replaceAllUsesWith(MM->getLHS());
540+
MM->eraseFromParent();
541+
return true;
542+
}
543+
if (RHS_CR.icmp(Pred, LHS_CR)) {
544+
++NumMinMax;
545+
MM->replaceAllUsesWith(MM->getRHS());
546+
MM->eraseFromParent();
547+
return true;
548+
}
549+
return false;
542550
}
543551

544552
// Rewrite this with.overflow intrinsic as non-overflowing.

llvm/test/Transforms/CorrelatedValuePropagation/min-max.ll

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ define i8 @test6(i8 %x) {
7171
; CHECK-LABEL: @test6(
7272
; CHECK-NEXT: [[LIM:%.*]] = icmp uge i8 [[X:%.*]], 42
7373
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
74-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
7574
; CHECK-NEXT: ret i8 42
7675
;
7776
%lim = icmp uge i8 %x, 42
@@ -119,7 +118,6 @@ define i8 @test10(i8 %x) {
119118
; CHECK-LABEL: @test10(
120119
; CHECK-NEXT: [[LIM:%.*]] = icmp ule i8 [[X:%.*]], 42
121120
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
122-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
123121
; CHECK-NEXT: ret i8 42
124122
;
125123
%lim = icmp ule i8 %x, 42
@@ -167,7 +165,6 @@ define i8 @test14(i8 %x) {
167165
; CHECK-LABEL: @test14(
168166
; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42
169167
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
170-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)
171168
; CHECK-NEXT: ret i8 42
172169
;
173170
%lim = icmp sge i8 %x, 42
@@ -215,7 +212,6 @@ define i8 @test18(i8 %x) {
215212
; CHECK-LABEL: @test18(
216213
; CHECK-NEXT: [[LIM:%.*]] = icmp sle i8 [[X:%.*]], 42
217214
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
218-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42)
219215
; CHECK-NEXT: ret i8 42
220216
;
221217
%lim = icmp sle i8 %x, 42
@@ -235,3 +231,62 @@ define i8 @test19(i8 %x) {
235231
%r = call i8 @llvm.smax(i8 %x, i8 42)
236232
ret i8 %r
237233
}
234+
235+
declare void @body(i32)
236+
237+
define void @test_bidirectional() {
238+
; CHECK-LABEL: @test_bidirectional(
239+
; CHECK-NEXT: entry:
240+
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
241+
; CHECK: for.body:
242+
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
243+
; CHECK-NEXT: call void @body(i32 65535)
244+
; CHECK-NEXT: [[INC]] = add nsw i32 [[INDVAR]], 1
245+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INDVAR]], 65535
246+
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[EXIT:%.*]]
247+
; CHECK: exit:
248+
; CHECK-NEXT: ret void
249+
;
250+
entry:
251+
br label %for.body
252+
253+
for.body:
254+
%indvar = phi i32 [ 0, %entry ], [ %inc, %for.body ]
255+
%smax = call i32 @llvm.smax.i32(i32 %indvar, i32 65535)
256+
call void @body(i32 %smax)
257+
%inc = add nsw i32 %indvar, 1
258+
%cmp = icmp slt i32 %indvar, 65535
259+
br i1 %cmp, label %for.body, label %exit
260+
261+
exit:
262+
ret void
263+
}
264+
265+
define i64 @test_at_use(i1 %cond, i64 %x) {
266+
; CHECK-LABEL: @test_at_use(
267+
; CHECK-NEXT: entry:
268+
; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[IF_END:%.*]]
269+
; CHECK: bb1:
270+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[X:%.*]], 0
271+
; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
272+
; CHECK: if.then:
273+
; CHECK-NEXT: ret i64 0
274+
; CHECK: if.end:
275+
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[X]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ]
276+
; CHECK-NEXT: ret i64 [[PHI]]
277+
;
278+
entry:
279+
br i1 %cond, label %bb1, label %if.end
280+
281+
bb1:
282+
%val = call i64 @llvm.smax.i64(i64 %x, i64 -1)
283+
%cmp = icmp slt i64 %x, 0
284+
br i1 %cmp, label %if.then, label %if.end
285+
286+
if.then:
287+
ret i64 0
288+
289+
if.end:
290+
%phi = phi i64 [%val, %bb1], [0, %entry]
291+
ret i64 %phi
292+
}

0 commit comments

Comments
 (0)