Skip to content

Commit ffdcb9b

Browse files
committed
address more comments
1 parent 7d41d85 commit ffdcb9b

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
570570
/// exensive modification of the IR is required.
571571
static Value *foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal,
572572
Value *FVal,
573-
InstCombiner::BuilderTy &Builder) {
573+
InstCombiner::BuilderTy &Builder,
574+
const SimplifyQuery &SQ) {
574575
const Value *CmpLHS = Cmp->getOperand(0);
575576
const Value *CmpRHS = Cmp->getOperand(1);
576577
const ICmpInst::Predicate Pred = Cmp->getPredicate();
@@ -579,7 +580,6 @@ static Value *foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal,
579580
// (X < Y) ? X : (Y + 1) ==> MAX(X, Y + 1)
580581
// This transformation is valid when overflow corresponding to the sign of
581582
// the comparison is poison and we must drop the non-matching overflow flag.
582-
// Note: that the UMIN case is not possible as we canonicalize to addition.
583583
if (CmpLHS == TVal) {
584584
if (Pred == CmpInst::ICMP_SGT &&
585585
match(FVal, m_NSWAddLike(m_Specific(CmpRHS), m_One()))) {
@@ -598,6 +598,15 @@ static Value *foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal,
598598
cast<Instruction>(FVal)->setHasNoSignedWrap(false);
599599
return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
600600
}
601+
602+
// Note: We must use isKnownNonZero here because "sub nuw %x, 1" will be
603+
// canonicalize to "add %x, -1" discarding the nuw flag.
604+
if (Pred == CmpInst::ICMP_ULT &&
605+
match(FVal, m_AddLike(m_Specific(CmpRHS), m_AllOnes())) &&
606+
isKnownNonZero(CmpRHS, SQ)) {
607+
cast<Instruction>(FVal)->setHasNoSignedWrap(false);
608+
return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);
609+
}
601610
}
602611
return nullptr;
603612
}
@@ -1954,7 +1963,7 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
19541963
return &SI;
19551964
}
19561965

1957-
if (Value *V = foldSelectICmpMinMax(ICI, TrueVal, FalseVal, Builder))
1966+
if (Value *V = foldSelectICmpMinMax(ICI, TrueVal, FalseVal, Builder, SQ))
19581967
return replaceInstUsesWith(SI, V);
19591968

19601969
if (Instruction *V =

llvm/test/Transforms/InstCombine/minmax-fold.ll

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,10 +1623,10 @@ define i32 @test_smax_add1_nsw(i32 %x, i32 %w) {
16231623
ret i32 %r
16241624
}
16251625

1626-
define i32 @test_umax_add1_nsw(i32 %x, i32 %w) {
1627-
; CHECK-LABEL: @test_umax_add1_nsw(
1628-
; CHECK-NEXT: [[X2:%.*]] = add nuw i32 [[W:%.*]], 1
1629-
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[X2]])
1626+
define i32 @test_umax_add1_nuw(i32 %x, i32 %w) {
1627+
; CHECK-LABEL: @test_umax_add1_nuw(
1628+
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[W:%.*]], 1
1629+
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[ADD]])
16301630
; CHECK-NEXT: ret i32 [[R]]
16311631
;
16321632
%cmp = icmp ugt i32 %x, %w
@@ -1635,6 +1635,18 @@ define i32 @test_umax_add1_nsw(i32 %x, i32 %w) {
16351635
ret i32 %r
16361636
}
16371637

1638+
define i32 @test_umin_sub1_nuw(i32 %x, i32 range(i32 1, 0) %w) {
1639+
; CHECK-LABEL: @test_umin_sub1_nuw(
1640+
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[W:%.*]], -1
1641+
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[SUB]])
1642+
; CHECK-NEXT: ret i32 [[R]]
1643+
;
1644+
%cmp = icmp ult i32 %x, %w
1645+
%sub = add i32 %w, -1
1646+
%r = select i1 %cmp, i32 %x, i32 %sub
1647+
ret i32 %r
1648+
}
1649+
16381650
define <2 x i16> @test_smin_sub1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {
16391651
; CHECK-LABEL: @test_smin_sub1_nsw_vec(
16401652
; CHECK-NEXT: [[SUB:%.*]] = add nsw <2 x i16> [[W:%.*]], splat (i16 -1)
@@ -1659,8 +1671,8 @@ define <2 x i16> @test_smax_add1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {
16591671
ret <2 x i16> %r
16601672
}
16611673

1662-
define <2 x i16> @test_umax_add1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {
1663-
; CHECK-LABEL: @test_umax_add1_nsw_vec(
1674+
define <2 x i16> @test_umax_add1_nuw_vec(<2 x i16> %x, <2 x i16> %w) {
1675+
; CHECK-LABEL: @test_umax_add1_nuw_vec(
16641676
; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i16> [[W:%.*]], splat (i16 1)
16651677
; CHECK-NEXT: [[R:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[ADD]])
16661678
; CHECK-NEXT: ret <2 x i16> [[R]]
@@ -1671,6 +1683,19 @@ define <2 x i16> @test_umax_add1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {
16711683
ret <2 x i16> %r
16721684
}
16731685

1686+
define <2 x i16> @test_umin_sub1_nuw_vec(<2 x i16> %x, <2 x i16> range(i16 1, 0) %w) {
1687+
; CHECK-LABEL: @test_umin_sub1_nuw_vec(
1688+
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i16> [[W:%.*]], splat (i16 -1)
1689+
; CHECK-NEXT: [[R:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[SUB]])
1690+
; CHECK-NEXT: ret <2 x i16> [[R]]
1691+
;
1692+
%cmp = icmp ult <2 x i16> %x, %w
1693+
%sub = add <2 x i16> %w, splat (i16 -1)
1694+
%r = select <2 x i1> %cmp, <2 x i16> %x, <2 x i16> %sub
1695+
ret <2 x i16> %r
1696+
}
1697+
1698+
16741699
define i32 @test_smin_sub1_nsw_drop_flags(i32 %x, i32 %w) {
16751700
; CHECK-LABEL: @test_smin_sub1_nsw_drop_flags(
16761701
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[W:%.*]]
@@ -1695,8 +1720,8 @@ define i32 @test_smax_add1_nsw_drop_flags(i32 %x, i32 %w) {
16951720
ret i32 %r
16961721
}
16971722

1698-
define i32 @test_umax_add1_nsw_drop_flags(i32 %x, i32 %w) {
1699-
; CHECK-LABEL: @test_umax_add1_nsw_drop_flags(
1723+
define i32 @test_umax_add1_nuw_drop_flags(i32 %x, i32 %w) {
1724+
; CHECK-LABEL: @test_umax_add1_nuw_drop_flags(
17001725
; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[W:%.*]], 1
17011726
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[ADD]])
17021727
; CHECK-NEXT: ret i32 [[R]]
@@ -1706,3 +1731,15 @@ define i32 @test_umax_add1_nsw_drop_flags(i32 %x, i32 %w) {
17061731
%r = select i1 %cmp, i32 %x, i32 %add
17071732
ret i32 %r
17081733
}
1734+
1735+
define i32 @test_umin_sub1_nuw_drop_flags(i32 %x, i32 range(i32 1, 0) %w) {
1736+
; CHECK-LABEL: @test_umin_sub1_nuw_drop_flags(
1737+
; CHECK-NEXT: [[SUB:%.*]] = add i32 [[W:%.*]], -1
1738+
; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[SUB]])
1739+
; CHECK-NEXT: ret i32 [[R]]
1740+
;
1741+
%cmp = icmp ult i32 %x, %w
1742+
%sub = add nsw i32 %w, -1
1743+
%r = select i1 %cmp, i32 %x, i32 %sub
1744+
ret i32 %r
1745+
}

0 commit comments

Comments
 (0)