Skip to content

Commit 97ad0f4

Browse files
authored
[DAGCombiner][RISCV] Don't propagate the exact flag from udiv/sdiv to urem/srem. (#145387)
If we simplify a udiv/sdiv using the exact flag we shouldn't propagate that simplifaction to any urem/srem that happens to use the same operands. If the exact flag is wrong, the udiv/sdiv will produce poison, but that doesn't mean we can make the urem/srem simplify to 0. Fixes #145360.
1 parent 06d78ba commit 97ad0f4

File tree

2 files changed

+100
-10
lines changed

2 files changed

+100
-10
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,11 +4961,15 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
49614961
// (Dividend - (Quotient * Divisor).
49624962
if (SDNode *RemNode = DAG.getNodeIfExists(ISD::SREM, N->getVTList(),
49634963
{ N0, N1 })) {
4964-
SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
4965-
SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
4966-
AddToWorklist(Mul.getNode());
4967-
AddToWorklist(Sub.getNode());
4968-
CombineTo(RemNode, Sub);
4964+
// If the sdiv has the exact flag we shouldn't propagate it to the
4965+
// remainder node.
4966+
if (!N->getFlags().hasExact()) {
4967+
SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
4968+
SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
4969+
AddToWorklist(Mul.getNode());
4970+
AddToWorklist(Sub.getNode());
4971+
CombineTo(RemNode, Sub);
4972+
}
49694973
}
49704974
return V;
49714975
}
@@ -5101,11 +5105,15 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
51015105
// (Dividend - (Quotient * Divisor).
51025106
if (SDNode *RemNode = DAG.getNodeIfExists(ISD::UREM, N->getVTList(),
51035107
{ N0, N1 })) {
5104-
SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
5105-
SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
5106-
AddToWorklist(Mul.getNode());
5107-
AddToWorklist(Sub.getNode());
5108-
CombineTo(RemNode, Sub);
5108+
// If the udiv has the exact flag we shouldn't propagate it to the
5109+
// remainder node.
5110+
if (!N->getFlags().hasExact()) {
5111+
SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, V, N1);
5112+
SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, N0, Mul);
5113+
AddToWorklist(Mul.getNode());
5114+
AddToWorklist(Sub.getNode());
5115+
CombineTo(RemNode, Sub);
5116+
}
51095117
}
51105118
return V;
51115119
}

llvm/test/CodeGen/RISCV/pr145360.ll

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=riscv64 -mattr=+m | FileCheck %s
3+
4+
define i32 @signed(i32 %0, ptr %1) {
5+
; CHECK-LABEL: signed:
6+
; CHECK: # %bb.0:
7+
; CHECK-NEXT: sraiw a2, a0, 31
8+
; CHECK-NEXT: srliw a2, a2, 24
9+
; CHECK-NEXT: add a2, a0, a2
10+
; CHECK-NEXT: andi a2, a2, -256
11+
; CHECK-NEXT: subw a2, a0, a2
12+
; CHECK-NEXT: sraiw a0, a0, 8
13+
; CHECK-NEXT: sw a2, 0(a1)
14+
; CHECK-NEXT: ret
15+
%rem = srem i32 %0, 256
16+
store i32 %rem, ptr %1, align 4
17+
%div = sdiv exact i32 %0, 256
18+
ret i32 %div
19+
}
20+
21+
define i32 @unsigned(i32 %0, ptr %1) {
22+
; CHECK-LABEL: unsigned:
23+
; CHECK: # %bb.0:
24+
; CHECK-NEXT: slli a2, a0, 32
25+
; CHECK-NEXT: lui a3, 699051
26+
; CHECK-NEXT: addi a3, a3, -1365
27+
; CHECK-NEXT: slli a4, a3, 32
28+
; CHECK-NEXT: mulhu a2, a2, a4
29+
; CHECK-NEXT: srli a2, a2, 36
30+
; CHECK-NEXT: slli a4, a2, 5
31+
; CHECK-NEXT: slli a2, a2, 3
32+
; CHECK-NEXT: subw a2, a2, a4
33+
; CHECK-NEXT: srliw a4, a0, 3
34+
; CHECK-NEXT: add a2, a0, a2
35+
; CHECK-NEXT: mulw a0, a4, a3
36+
; CHECK-NEXT: sw a2, 0(a1)
37+
; CHECK-NEXT: ret
38+
%rem = urem i32 %0, 24
39+
store i32 %rem, ptr %1, align 4
40+
%div = udiv exact i32 %0, 24
41+
ret i32 %div
42+
}
43+
44+
define i32 @signed_div_first(i32 %0, ptr %1) {
45+
; CHECK-LABEL: signed_div_first:
46+
; CHECK: # %bb.0:
47+
; CHECK-NEXT: sraiw a2, a0, 31
48+
; CHECK-NEXT: srliw a2, a2, 24
49+
; CHECK-NEXT: add a3, a0, a2
50+
; CHECK-NEXT: sraiw a2, a3, 8
51+
; CHECK-NEXT: andi a3, a3, -256
52+
; CHECK-NEXT: subw a0, a0, a3
53+
; CHECK-NEXT: sw a0, 0(a1)
54+
; CHECK-NEXT: mv a0, a2
55+
; CHECK-NEXT: ret
56+
%div = sdiv exact i32 %0, 256
57+
%rem = srem i32 %0, 256
58+
store i32 %rem, ptr %1, align 4
59+
ret i32 %div
60+
}
61+
62+
define i32 @unsigned_div_first(i32 %0, ptr %1) {
63+
; CHECK-LABEL: unsigned_div_first:
64+
; CHECK: # %bb.0:
65+
; CHECK-NEXT: slli a2, a0, 32
66+
; CHECK-NEXT: lui a3, 699051
67+
; CHECK-NEXT: addi a3, a3, -1365
68+
; CHECK-NEXT: slli a3, a3, 32
69+
; CHECK-NEXT: mulhu a2, a2, a3
70+
; CHECK-NEXT: srli a2, a2, 36
71+
; CHECK-NEXT: slli a3, a2, 5
72+
; CHECK-NEXT: slli a4, a2, 3
73+
; CHECK-NEXT: subw a4, a4, a3
74+
; CHECK-NEXT: add a0, a0, a4
75+
; CHECK-NEXT: sw a0, 0(a1)
76+
; CHECK-NEXT: mv a0, a2
77+
; CHECK-NEXT: ret
78+
%div = udiv exact i32 %0, 24
79+
%rem = urem i32 %0, 24
80+
store i32 %rem, ptr %1, align 4
81+
ret i32 %div
82+
}

0 commit comments

Comments
 (0)