Skip to content

Commit fb070a0

Browse files
committed
[CVP] Canonicalize signed minmax into unsigned
1 parent bdb0f47 commit fb070a0

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ STATISTIC(NumSaturating,
9090
"Number of saturating arithmetics converted to normal arithmetics");
9191
STATISTIC(NumNonNull, "Number of function pointer arguments marked non-null");
9292
STATISTIC(NumMinMax, "Number of llvm.[us]{min,max} intrinsics removed");
93+
STATISTIC(NumSMinMax,
94+
"Number of llvm.s{min,max} intrinsics simplified to unsigned");
9395
STATISTIC(NumUDivURemsNarrowedExpanded,
9496
"Number of bound udiv's/urem's expanded");
9597
STATISTIC(NumZExt, "Number of non-negative deductions");
@@ -528,17 +530,35 @@ static bool processAbsIntrinsic(IntrinsicInst *II, LazyValueInfo *LVI) {
528530
}
529531

530532
// See if this min/max intrinsic always picks it's one specific operand.
533+
// If not, check whether we can canonicalize signed minmax into unsigned version
531534
static bool processMinMaxIntrinsic(MinMaxIntrinsic *MM, LazyValueInfo *LVI) {
532535
CmpInst::Predicate Pred = CmpInst::getNonStrictPredicate(MM->getPredicate());
533536
LazyValueInfo::Tristate Result = LVI->getPredicateAt(
534537
Pred, MM->getLHS(), MM->getRHS(), MM, /*UseBlockValue=*/true);
535-
if (Result == LazyValueInfo::Unknown)
536-
return false;
538+
if (Result != LazyValueInfo::Unknown) {
539+
++NumMinMax;
540+
MM->replaceAllUsesWith(MM->getOperand(!Result));
541+
MM->eraseFromParent();
542+
return true;
543+
}
537544

538-
++NumMinMax;
539-
MM->replaceAllUsesWith(MM->getOperand(!Result));
540-
MM->eraseFromParent();
541-
return true;
545+
if (MM->isSigned() &&
546+
ConstantRange::areInsensitiveToSignednessOfICmpPredicate(
547+
LVI->getConstantRangeAtUse(MM->getOperandUse(0),
548+
/*UndefAllowed*/ true),
549+
LVI->getConstantRangeAtUse(MM->getOperandUse(1),
550+
/*UndefAllowed*/ true))) {
551+
++NumSMinMax;
552+
IRBuilder<> B(MM);
553+
MM->replaceAllUsesWith(B.CreateBinaryIntrinsic(
554+
MM->getIntrinsicID() == Intrinsic::smin ? Intrinsic::umin
555+
: Intrinsic::umax,
556+
MM->getLHS(), MM->getRHS()));
557+
MM->eraseFromParent();
558+
return true;
559+
}
560+
561+
return false;
542562
}
543563

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

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

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ define i8 @test14(i8 %x) {
167167
; CHECK-LABEL: @test14(
168168
; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 42
169169
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
170-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)
170+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
171171
; CHECK-NEXT: ret i8 42
172172
;
173173
%lim = icmp sge i8 %x, 42
@@ -179,8 +179,8 @@ define i8 @test15(i8 %x) {
179179
; CHECK-LABEL: @test15(
180180
; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41
181181
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
182-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smin.i8(i8 [[X]], i8 42)
183-
; CHECK-NEXT: ret i8 [[R]]
182+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[X]], i8 42)
183+
; CHECK-NEXT: ret i8 [[TMP1]]
184184
;
185185
%lim = icmp sge i8 %x, 41
186186
call void @llvm.assume(i1 %lim)
@@ -192,8 +192,8 @@ define i8 @test16(i8 %x) {
192192
; CHECK-LABEL: @test16(
193193
; CHECK-NEXT: [[LIM:%.*]] = icmp sge i8 [[X:%.*]], 41
194194
; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]])
195-
; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 42)
196-
; CHECK-NEXT: ret i8 [[R]]
195+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X]], i8 42)
196+
; CHECK-NEXT: ret i8 [[TMP1]]
197197
;
198198
%lim = icmp sge i8 %x, 41
199199
call void @llvm.assume(i1 %lim)
@@ -240,8 +240,8 @@ define i8 @test_smax_to_umax_nneg(i8 %a, i8 %b) {
240240
; CHECK-LABEL: @test_smax_to_umax_nneg(
241241
; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127
242242
; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127
243-
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
244-
; CHECK-NEXT: ret i8 [[RET]]
243+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
244+
; CHECK-NEXT: ret i8 [[TMP1]]
245245
;
246246
%nneg_a = and i8 %a, 127
247247
%nneg_b = and i8 %b, 127
@@ -253,8 +253,8 @@ define i8 @test_smax_to_umax_neg(i8 %a, i8 %b) {
253253
; CHECK-LABEL: @test_smax_to_umax_neg(
254254
; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128
255255
; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128
256-
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smax.i8(i8 [[NEG_A]], i8 [[NEG_B]])
257-
; CHECK-NEXT: ret i8 [[RET]]
256+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[NEG_A]], i8 [[NEG_B]])
257+
; CHECK-NEXT: ret i8 [[TMP1]]
258258
;
259259
%neg_a = or i8 %a, 128
260260
%neg_b = or i8 %b, 128
@@ -266,8 +266,8 @@ define i8 @test_smin_to_umin_nneg(i8 %a, i8 %b) {
266266
; CHECK-LABEL: @test_smin_to_umin_nneg(
267267
; CHECK-NEXT: [[NNEG_A:%.*]] = and i8 [[A:%.*]], 127
268268
; CHECK-NEXT: [[NNEG_B:%.*]] = and i8 [[B:%.*]], 127
269-
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smin.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
270-
; CHECK-NEXT: ret i8 [[RET]]
269+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NNEG_A]], i8 [[NNEG_B]])
270+
; CHECK-NEXT: ret i8 [[TMP1]]
271271
;
272272
%nneg_a = and i8 %a, 127
273273
%nneg_b = and i8 %b, 127
@@ -279,8 +279,8 @@ define i8 @test_smin_to_umin_neg(i8 %a, i8 %b) {
279279
; CHECK-LABEL: @test_smin_to_umin_neg(
280280
; CHECK-NEXT: [[NEG_A:%.*]] = or i8 [[A:%.*]], -128
281281
; CHECK-NEXT: [[NEG_B:%.*]] = or i8 [[B:%.*]], -128
282-
; CHECK-NEXT: [[RET:%.*]] = call i8 @llvm.smin.i8(i8 [[NEG_A]], i8 [[NEG_B]])
283-
; CHECK-NEXT: ret i8 [[RET]]
282+
; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[NEG_A]], i8 [[NEG_B]])
283+
; CHECK-NEXT: ret i8 [[TMP1]]
284284
;
285285
%neg_a = or i8 %a, 128
286286
%neg_b = or i8 %b, 128

0 commit comments

Comments
 (0)