Skip to content

Commit 5d6aba5

Browse files
committed
fix crash
1 parent 00d8f91 commit 5d6aba5

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -585,29 +585,31 @@ static Value *foldSelectICmpMinMax(const ICmpInst *Cmp, Value *TVal,
585585
Pred = CmpInst::getSwappedPredicate(Pred);
586586
}
587587

588-
if (CmpLHS == TVal) {
588+
// TODO: consider handeling 'or disjoint' as well, though these would need to
589+
// be converted to 'add' instructions.
590+
if (CmpLHS == TVal && isa<Instruction>(FVal)) {
589591
if (Pred == CmpInst::ICMP_SGT &&
590-
match(FVal, m_NSWAddLike(m_Specific(CmpRHS), m_One()))) {
592+
match(FVal, m_NSWAdd(m_Specific(CmpRHS), m_One()))) {
591593
cast<Instruction>(FVal)->setHasNoUnsignedWrap(false);
592594
return Builder.CreateBinaryIntrinsic(Intrinsic::smax, TVal, FVal);
593595
}
594596

595597
if (Pred == CmpInst::ICMP_SLT &&
596-
match(FVal, m_NSWAddLike(m_Specific(CmpRHS), m_AllOnes()))) {
598+
match(FVal, m_NSWAdd(m_Specific(CmpRHS), m_AllOnes()))) {
597599
cast<Instruction>(FVal)->setHasNoUnsignedWrap(false);
598600
return Builder.CreateBinaryIntrinsic(Intrinsic::smin, TVal, FVal);
599601
}
600602

601603
if (Pred == CmpInst::ICMP_UGT &&
602-
match(FVal, m_NUWAddLike(m_Specific(CmpRHS), m_One()))) {
604+
match(FVal, m_NUWAdd(m_Specific(CmpRHS), m_One()))) {
603605
cast<Instruction>(FVal)->setHasNoSignedWrap(false);
604606
return Builder.CreateBinaryIntrinsic(Intrinsic::umax, TVal, FVal);
605607
}
606608

607609
// Note: We must use isKnownNonZero here because "sub nuw %x, 1" will be
608610
// canonicalize to "add %x, -1" discarding the nuw flag.
609611
if (Pred == CmpInst::ICMP_ULT &&
610-
match(FVal, m_AddLike(m_Specific(CmpRHS), m_AllOnes())) &&
612+
match(FVal, m_Add(m_Specific(CmpRHS), m_AllOnes())) &&
611613
isKnownNonZero(CmpRHS, SQ)) {
612614
cast<Instruction>(FVal)->setHasNoSignedWrap(false);
613615
return Builder.CreateBinaryIntrinsic(Intrinsic::umin, TVal, FVal);

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,3 +1791,54 @@ define i32 @test_umin_sub1_nuw_drop_flags(i32 %x, i32 range(i32 1, 0) %w) {
17911791
%r = select i1 %cmp, i32 %x, i32 %sub
17921792
ret i32 %r
17931793
}
1794+
1795+
;; Confirm we don't crash on these cases.
1796+
define i32 @test_smin_or_neg1_nsw(i32 %x, i32 %w) {
1797+
; CHECK-LABEL: @test_smin_or_neg1_nsw(
1798+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[W:%.*]]
1799+
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -1
1800+
; CHECK-NEXT: ret i32 [[R]]
1801+
;
1802+
%cmp = icmp slt i32 %x, %w
1803+
%sub = or disjoint i32 %w, -1
1804+
%r = select i1 %cmp, i32 %x, i32 %sub
1805+
ret i32 %r
1806+
}
1807+
1808+
define i32 @test_smax_or_1_nsw(i32 %x, i32 %w) {
1809+
; CHECK-LABEL: @test_smax_or_1_nsw(
1810+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[W:%.*]]
1811+
; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[W]], 1
1812+
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[ADD]]
1813+
; CHECK-NEXT: ret i32 [[R]]
1814+
;
1815+
%cmp = icmp sgt i32 %x, %w
1816+
%add = or disjoint i32 %w, 1
1817+
%r = select i1 %cmp, i32 %x, i32 %add
1818+
ret i32 %r
1819+
}
1820+
1821+
define i32 @test_umax_or_1_nuw(i32 %x, i32 %w) {
1822+
; CHECK-LABEL: @test_umax_or_1_nuw(
1823+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[W:%.*]]
1824+
; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[W]], 1
1825+
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[ADD]]
1826+
; CHECK-NEXT: ret i32 [[R]]
1827+
;
1828+
%cmp = icmp ugt i32 %x, %w
1829+
%add = or disjoint i32 %w, 1
1830+
%r = select i1 %cmp, i32 %x, i32 %add
1831+
ret i32 %r
1832+
}
1833+
1834+
define i32 @test_umin_or_neg1_nuw(i32 %x, i32 range(i32 1, 0) %w) {
1835+
; CHECK-LABEL: @test_umin_or_neg1_nuw(
1836+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[W:%.*]]
1837+
; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -1
1838+
; CHECK-NEXT: ret i32 [[R]]
1839+
;
1840+
%cmp = icmp ult i32 %x, %w
1841+
%sub = or disjoint i32 %w, -1
1842+
%r = select i1 %cmp, i32 %x, i32 %sub
1843+
ret i32 %r
1844+
}

0 commit comments

Comments
 (0)