8000 [DAGCombiner] Fix the "subtraction if above a constant threshold" tra… · pfusik/llvm-project@3748ec1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3748ec1

Browse files
committed
[DAGCombiner] Fix the "subtraction if above a constant threshold" transform
This fixes llvm#135194 incorrectly leaving `add nuw/nsw` while an unsigned wrap is expected.
1 parent 849ecbc commit 3748ec1

File tree

3 files changed

+40
-15
lines changed

3 files changed

+40
-15
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12136,15 +12136,19 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
1213612136
if (SDValue NewSel = SimplifySelect(DL, N0, N1, N2))
1213712137
return NewSel;
1213812138

12139-
// (select (ugt x, C), (add x, ~C), x) -> (umin (add x, ~C), x)
12139+
// (select (ugt x, C), (add x, ~C), x) -> (umin x, (add x, ~C))
1214012140
// (select (ult x, C), x, (add x, -C)) -> (umin x, (add x, -C))
1214112141
APInt C;
1214212142
if (sd_match(Cond1, m_ConstInt(C)) && hasUMin(VT)) {
12143+
APInt AddC;
1214312144
if ((CC == ISD::SETUGT && Cond0 == N2 &&
12144-
sd_match(N1, m_Add(m_Specific(N2), m_SpecificInt(~C)))) ||
12145+
sd_match(N1, m_Add(m_Specific(N2), m_ConstInt(AddC))) &&
12146+
AddC == ~C) ||
1214512147
(CC == ISD::SETULT && Cond0 == N1 &&
12146-
sd_match(N2, m_Add(m_Specific(N1), m_S 8000 pecificInt(-C)))))
12147-
return DAG.getNode(ISD::UMIN, DL, VT, N1, N2);
12148+
sd_match(N2, m_Add(m_Specific(N1), m_ConstInt(AddC))) && AddC == -C))
12149+
return DAG.getNode(ISD::UMIN, DL, VT, Cond0,
12150+
DAG.getNode(ISD::ADD, DL, VT, Cond0,
12151+
DAG.getConstant(AddC, DL, VT)));
1214812152
}
1214912153
}
1215012154

llvm/test/CodeGen/RISCV/rv32zbb.ll

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,7 +1742,7 @@ define i8 @sub_if_uge_C_i8(i8 zeroext %x) {
17421742
; RV32ZBB: # %bb.0:
17431743
; RV32ZBB-NEXT: addi a1, a0, -13
17441744
; RV32ZBB-NEXT: zext.b a1, a1
1745-
; RV32ZBB-NEXT: minu a0, a1, a0
1745+
; RV32ZBB-NEXT: minu a0, a0, a1
17461746
; RV32ZBB-NEXT: ret
17471747
%cmp = icmp ugt i8 %x, 12
17481748
%sub = add i8 %x, -13
@@ -1763,7 +1763,7 @@ define i16 @sub_if_uge_C_i16(i16 zeroext %x) {
17631763
; RV32ZBB: # %bb.0:
17641764
; RV32ZBB-NEXT: addi a1, a0, -251
17651765
; RV32ZBB-NEXT: zext.h a1, a1
1766-
; RV32ZBB-NEXT: minu a0, a1, a0
1766+
; RV32ZBB-NEXT: minu a0, a0, a1
17671767
; RV32ZBB-NEXT: ret
17681768
%cmp = icmp ugt i16 %x, 250
17691769
%sub = add i16 %x, -251
@@ -1789,7 +1789,7 @@ define i32 @sub_if_uge_C_i32(i32 signext %x) {
17891789
; RV32ZBB-NEXT: lui a1, 1048560
17901790
; RV32ZBB-NEXT: addi a1, a1, 15
17911791
; RV32ZBB-NEXT: add a1, a0, a1
1792-
; RV32ZBB-NEXT: minu a0, a1, a0
1792+
; RV32ZBB-NEXT: minu a0, a0, a1
17931793
; RV32ZBB-NEXT: ret
17941794
%cmp = icmp ugt i32 %x, 65520
17951795
%sub = add i32 %x, -65521
@@ -1850,7 +1850,7 @@ define i32 @sub_if_uge_C_multiuse_cmp_i32(i32 signext %x, ptr %z) {
18501850
; RV32ZBB-NEXT: addi a3, a3, 15
18511851
; RV32ZBB-NEXT: sltu a2, a2, a0
18521852
; RV32ZBB-NEXT: add a3, a0, a3
1853-
; RV32ZBB-NEXT: minu a0, a3, a0
1853+
; RV32ZBB-NEXT: minu a0, a0, a3
18541854
; RV32ZBB-NEXT: sw a2, 0(a1)
18551855
; RV32ZBB-NEXT: ret
18561856
%cmp = icmp ugt i32 %x, 65520
@@ -1882,7 +1882,7 @@ define i32 @sub_if_uge_C_multiuse_sub_i32(i32 signext %x, ptr %z) {
18821882
; RV32ZBB-NEXT: lui a2, 1048560
18831883
; RV32ZBB-NEXT: addi a2, a2, 15
18841884
; RV32ZBB-NEXT: add a2, a0, a2
1885-
; RV32ZBB-NEXT: minu a0, a2, a0
1885+
; RV32ZBB-NEXT: minu a0, a0, a2
18861886
; RV32ZBB-NEXT: sw a2, 0(a1)
18871887
; RV32ZBB-NEXT: ret
18881888
%sub = add i32 %x, -65521
@@ -1917,3 +1917,24 @@ define i32 @sub_if_uge_C_swapped_i32(i32 %x) {
19171917
%cond = select i1 %cmp, i32 %x, i32 %sub
19181918
ret i32 %cond
19191919
}
1920+
1921+
define noundef i8 @sub_if_uge_C_nsw_i8(i8 zeroext %x) {
1922+
; RV32I-LABEL: sub_if_uge_C_nsw_i8:
1923+
; RV32I: # %bb.0:
1924+
; RV32I-NEXT: sltiu a1, a0, 13
1925+
; RV32I-NEXT: addi a1, a1, -1
1926+
; RV32I-NEXT: andi a1, a1, -13
1927+
; RV32I-NEXT: add a0, a0, a1
1928+
; RV32I-NEXT: ret
1929+
;
1930+
; RV32ZBB-LABEL: sub_if_uge_C_nsw_i8:
1931+
; RV32ZBB: # %bb.0:
1932+
; RV32ZBB-NEXT: addi a1, a0, -13
1933+
; RV32ZBB-NEXT: zext.b a1, a1
1934+
; RV32ZBB-NEXT: minu a0, a0, a1
1935+
; RV32ZBB-NEXT: ret
1936+
%cmp = icmp ugt i8 %x, 12
1937+
%sub = add nsw i8 %x, -13
1938+
%conv4 = select i1 %cmp, i8 %sub, i8 %x
1939+
ret i8 %conv4
1940+
}

llvm/test/CodeGen/RISCV/rv64zbb.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,7 +1898,7 @@ define i8 @sub_if_uge_C_i8(i8 zeroext %x) {
18981898
; RV64ZBB: # %bb.0:
18991899
; RV64ZBB-NEXT: addi a1, a0, -13
19001900
; RV64ZBB-NEXT: zext.b a1, a1
1901-
; RV64ZBB-NEXT: minu a0, a1, a0
1901+
; RV64ZBB-NEXT: minu a0, a0, a1
19021902
; RV64ZBB-NEXT: ret
19031903
%cmp = icmp ugt i8 %x, 12
19041904
%sub = add i8 %x, -13
@@ -1919,7 +1919,7 @@ define i16 @sub_if_uge_C_i16(i16 zeroext %x) {
19191919
; RV64ZBB: # %bb.0:
19201920
; RV64ZBB-NEXT: addi a1, a0, -251
19211921
; RV64ZBB-NEXT: zext.h a1, a1
1922-
; RV64ZBB-NEXT: minu a0, a1, a0
1922+
; RV64ZBB-NEXT: minu a0, a0, a1
19231923
; RV64ZBB-NEXT: ret
19241924
%cmp = icmp ugt i16 %x, 250
19251925
%sub = add i16 %x, -251
@@ -1945,7 +1945,7 @@ define i32 @sub_if_uge_C_i32(i32 signext %x) {
19451945
; RV64ZBB-NEXT: lui a1, 1048560
19461946
; RV64ZBB-NEXT: addi a1, a1, 15
19471947
; RV64ZBB-NEXT: addw a1, a0, a1
1948-
; RV64ZBB-NEXT: minu a0, a1, a0
1948+
; RV64ZBB-NEXT: minu a0, a0, a1
19491949
; RV64ZBB-NEXT: ret
19501950
%cmp = icmp ugt i32 %x, 65520
19511951
%sub = add i32 %x, -65521
@@ -1975,7 +1975,7 @@ define i64 @sub_if_uge_C_i64(i64 %x) {
19751975
; RV64ZBB-NEXT: addiw a1, a1, -761
19761976
; RV64ZBB-NEXT: slli a1, a1, 9
19771977
; RV64ZBB-NEXT: add a1, a0, a1
1978-
; RV64ZBB-NEXT: minu a0, a1, a0
1978+
; RV64ZBB-NEXT: minu a0, a0, a1
19791979
; RV64ZBB-NEXT: ret
19801980
%cmp = icmp ugt i64 %x, 4999999999
19811981
%sub = add i64 %x, -5000000000
@@ -2005,7 +2005,7 @@ define i32 @sub_if_uge_C_multiuse_cmp_i32(i32 signext %x, ptr %z) {
20052005
; RV64ZBB-NEXT: addi a3, a3, 15
20062006
; RV64ZBB-NEXT: sltu a2, a2, a0
20072007
; RV64ZBB-NEXT: addw a3, a0, a3
2008-
; RV64ZBB-NEXT: minu a0, a3, a0
2008+
; RV64ZBB-NEXT: minu a0, a0, a3
20092009
; RV64ZBB-NEXT: sw a2, 0(a1)
20102010
; RV64ZBB-NEXT: ret
20112011
%cmp = icmp ugt i32 %x, 65520
@@ -2037,7 +2037,7 @@ define i32 @sub_if_uge_C_multiuse_sub_i32(i32 signext %x, ptr %z) {
20372037
; RV64ZBB-NEXT: lui a2, 1048560
20382038
; RV64ZBB-NEXT: addi a2, a2, 15
20392039
; RV64ZBB-NEXT: addw a2, a0, a2
2040-
; RV64ZBB-NEXT: minu a0, a2, a0
2040+
; RV64ZBB-NEXT: minu a0, a0, a2
20412041
; RV64ZBB-NEXT: sw a2, 0(a1)
20422042
; RV64ZBB-NEXT: ret
20432043
%sub = add i32 %x, -65521

0 commit comments

Comments
 (0)
0