Skip to content

Commit 568e0a6

Browse files
committed
[DAGCombiner] Push freeze through SETCC and SELECT_CC
Allow pushing freeze through SETCC and SELECT_CC even if there are multiple "maybe poison" operands. In the past we have limited it to a single "maybe poison" operand, but it seems profitable to also allow the multiple operand scenario. One goal here is to avoid some regressions seen in review of #84924 when solving the select->and miscompiles described in #84653
1 parent ae73863 commit 568e0a6

15 files changed

+555
-489
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15442,7 +15442,9 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1544215442
N0->getNumValues() != 1 || !N0->hasOneUse())
1544315443
return SDValue();
1544415444

15445-
bool AllowMultipleMaybePoisonOperands = N0.getOpcode() == ISD::BUILD_VECTOR ||
15445+
bool AllowMultipleMaybePoisonOperands = N0.getOpcode() == ISD::SELECT_CC ||
15446+
N0.getOpcode() == ISD::SETCC ||
15447+
N0.getOpcode() == ISD::BUILD_VECTOR ||
1544615448
N0.getOpcode() == ISD::BUILD_PAIR ||
1544715449
N0.getOpcode() == ISD::CONCAT_VECTORS;
1544815450

llvm/test/CodeGen/AArch64/cmp-chains.ll

Lines changed: 119 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@
66

77
; (x0 < x1) && (x2 > x3)
88
define i32 @cmp_and2(i32 %0, i32 %1, i32 %2, i32 %3) {
9-
; CHECK-LABEL: cmp_and2:
10-
; CHECK: // %bb.0:
11-
; CHECK-NEXT: cmp w0, w1
12-
; CHECK-NEXT: cset w8, lo
13-
; CHECK-NEXT: cmp w2, w3
14-
; CHECK-NEXT: cset w9, hi
15-
; CHECK-NEXT: and w0, w8, w9
16-
; CHECK-NEXT: ret
9+
; SDISEL-LABEL: cmp_and2:
10+
; SDISEL: // %bb.0:
11+
; SDISEL-NEXT: cmp w0, w1
12+
; SDISEL-NEXT: ccmp w2, w3, #0, lo
13+
; SDISEL-NEXT: cset w0, hi
14+
; SDISEL-NEXT: ret
15+
;
16+
; GISEL-LABEL: cmp_and2:
17+
; GISEL: // %bb.0:
18+
; GISEL-NEXT: cmp w0, w1
19+
; GISEL-NEXT: cset w8, lo
20+
; GISEL-NEXT: cmp w2, w3
21+
; GISEL-NEXT: cset w9, hi
22+
; GISEL-NEXT: and w0, w8, w9
23+
; GISEL-NEXT: ret
1724
%5 = icmp ult i32 %0, %1
1825
%6 = icmp ugt i32 %2, %3
1926
%7 = select i1 %5, i1 %6, i1 false
@@ -23,17 +30,25 @@ define i32 @cmp_and2(i32 %0, i32 %1, i32 %2, i32 %3) {
2330

2431
; (x0 < x1) && (x2 > x3) && (x4 != x5)
2532
define i32 @cmp_and3(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5) {
26-
; CHECK-LABEL: cmp_and3:
27-
; CHECK: // %bb.0:
28-
; CHECK-NEXT: cmp w0, w1
29-
; CHECK-NEXT: cset w8, lo
30-
; CHECK-NEXT: cmp w2, w3
31-
; CHECK-NEXT: cset w9, hi
32-
; CHECK-NEXT: cmp w4, w5
33-
; CHECK-NEXT: and w8, w8, w9
34-
; CHECK-NEXT: cset w9, ne
35-
; CHECK-NEXT: and w0, w8, w9
36-
; CHECK-NEXT: ret
33+
; SDISEL-LABEL: cmp_and3:
34+
; SDISEL: // %bb.0:
35+
; SDISEL-NEXT: cmp w0, w1
36+
; SDISEL-NEXT: ccmp w2, w3, #0, lo
37+
; SDISEL-NEXT: ccmp w4, w5, #4, hi
38+
; SDISEL-NEXT: cset w0, ne
39+
; SDISEL-NEXT: ret
40+
;
41+
; GISEL-LABEL: cmp_and3:
42+
; GISEL: // %bb.0:
43+
; GISEL-NEXT: cmp w0, w1
44+
; GISEL-NEXT: cset w8, lo
45+
; GISEL-NEXT: cmp w2, w3
46+
; GISEL-NEXT: cset w9, hi
47+
; GISEL-NEXT: cmp w4, w5
48+
; GISEL-NEXT: and w8, w8, w9
49+
; GISEL-NEXT: cset w9, ne
50+
; GISEL-NEXT: and w0, w8, w9
51+
; GISEL-NEXT: ret
3752
%7 = icmp ult i32 %0, %1
3853
%8 = icmp ugt i32 %2, %3
3954
%9 = select i1 %7, i1 %8, i1 false
@@ -45,20 +60,29 @@ define i32 @cmp_and3(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5) {
4560

4661
; (x0 < x1) && (x2 > x3) && (x4 != x5) && (x6 == x7)
4762
define i32 @cmp_and4(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7) {
48-
; CHECK-LABEL: cmp_and4:
49-
; CHECK: // %bb.0:
50-
; CHECK-NEXT: cmp w2, w3
51-
; CHECK-NEXT: cset w8, hi
52-
; CHECK-NEXT: cmp w0, w1
53-
; CHECK-NEXT: cset w9, lo
54-
; CHECK-NEXT: cmp w4, w5
55-
; CHECK-NEXT: cset w10, ne
56-
; CHECK-NEXT: cmp w6, w7
57-
; CHECK-NEXT: and w8, w8, w9
58-
; CHECK-NEXT: cset w11, eq
59-
; CHECK-NEXT: and w9, w10, w11
60-
; CHECK-NEXT: and w0, w8, w9
61-
; CHECK-NEXT: ret
63+
; SDISEL-LABEL: cmp_and4:
64+
; SDISEL: // %bb.0:
65+
; SDISEL-NEXT: cmp w2, w3
66+
; SDISEL-NEXT: ccmp w0, w1, #2, hi
67+
; SDISEL-NEXT: ccmp w4, w5, #4, lo
68+
; SDISEL-NEXT: ccmp w6, w7, #0, ne
69+
; SDISEL-NEXT: cset w0, eq
70+
; SDISEL-NEXT: ret
71+
;
72+
; GISEL-LABEL: cmp_and4:
73+
; GISEL: // %bb.0:
74+
; GISEL-NEXT: cmp w2, w3
75+
; GISEL-NEXT: cset w8, hi
76+
; GISEL-NEXT: cmp w0, w1
77+
; GISEL-NEXT: cset w9, lo
78+
; GISEL-NEXT: cmp w4, w5
79+
; GISEL-NEXT: cset w10, ne
80+
; GISEL-NEXT: cmp w6, w7
81+
; GISEL-NEXT: and w8, w8, w9
82+
; GISEL-NEXT: cset w11, eq
83+
; GISEL-NEXT: and w9, w10, w11
84+
; GISEL-NEXT: and w0, w8, w9
85+
; GISEL-NEXT: ret
6286
%9 = icmp ugt i32 %2, %3
6387
%10 = icmp ult i32 %0, %1
6488
%11 = select i1 %9, i1 %10, i1 false
@@ -72,15 +96,22 @@ define i32 @cmp_and4(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32
7296

7397
; (x0 < x1) || (x2 > x3)
7498
define i32 @cmp_or2(i32 %0, i32 %1, i32 %2, i32 %3) {
75-
; CHECK-LABEL: cmp_or2:
76-
; CHECK: // %bb.0:
77-
; CHECK-NEXT: cmp w0, w1
78-
; CHECK-NEXT: cset w8, lo
79-
; CHECK-NEXT: cmp w2, w3
80-
; CHECK-NEXT: cset w9, ne
81-
; CHECK-NEXT: orr w8, w8, w9
82-
; CHECK-NEXT: and w0, w8, #0x1
83-
; CHECK-NEXT: ret
99+
; SDISEL-LABEL: cmp_or2:
100+
; SDISEL: // %bb.0:
101+
; SDISEL-NEXT: cmp w0, w1
102+
; SDISEL-NEXT: ccmp w2, w3, #0, hs
103+
; SDISEL-NEXT: cset w0, ne
104+
; SDISEL-NEXT: ret
105+
;
106+
; GISEL-LABEL: cmp_or2:
107+
; GISEL: // %bb.0:
108+
; GISEL-NEXT: cmp w0, w1
109+
; GISEL-NEXT: cset w8, lo
110+
; GISEL-NEXT: cmp w2, w3
111+
; GISEL-NEXT: cset w9, ne
112+
; GISEL-NEXT: orr w8, w8, w9
113+
; GISEL-NEXT: and w0, w8, #0x1
114+
; GISEL-NEXT: ret
84115
%5 = icmp ult i32 %0, %1
85116
%6 = icmp ne i32 %2, %3
86117
%7 = select i1 %5, i1 true, i1 %6
@@ -90,18 +121,26 @@ define i32 @cmp_or2(i32 %0, i32 %1, i32 %2, i32 %3) {
90121

91122
; (x0 < x1) || (x2 > x3) || (x4 != x5)
92123
define i32 @cmp_or3(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5) {
93-
; CHECK-LABEL: cmp_or3:
94-
; CHECK: // %bb.0:
95-
; CHECK-NEXT: cmp w0, w1
96-
; CHECK-NEXT: cset w8, lo
97-
; CHECK-NEXT: cmp w2, w3
98-
; CHECK-NEXT: cset w9, hi
99-
; CHECK-NEXT: cmp w4, w5
100-
; CHECK-NEXT: orr w8, w8, w9
101-
; CHECK-NEXT: cset w9, ne
102-
; CHECK-NEXT: orr w8, w8, w9
103-
; CHECK-NEXT: and w0, w8, #0x1
104-
; CHECK-NEXT: ret
124+
; SDISEL-LABEL: cmp_or3:
125+
; SDISEL: // %bb.0:
126+
; SDISEL-NEXT: cmp w0, w1
127+
; SDISEL-NEXT: ccmp w2, w3, #2, hs
128+
; SDISEL-NEXT: ccmp w4, w5, #0, ls
129+
; SDISEL-NEXT: cset w0, ne
130+
; SDISEL-NEXT: ret
131+
;
132+
; GISEL-LABEL: cmp_or3:
133+
; GISEL: // %bb.0:
134+
; GISEL-NEXT: cmp w0, w1
135+
; GISEL-NEXT: cset w8, lo
136+
; GISEL-NEXT: cmp w2, w3
137+
; GISEL-NEXT: cset w9, hi
138+
; GISEL-NEXT: cmp w4, w5
139+
; GISEL-NEXT: orr w8, w8, w9
140+
; GISEL-NEXT: cset w9, ne
141+
; GISEL-NEXT: orr w8, w8, w9
142+
; GISEL-NEXT: and w0, w8, #0x1
143+
; GISEL-NEXT: ret
105144
%7 = icmp ult i32 %0, %1
106145
%8 = icmp ugt i32 %2, %3
107146
%9 = select i1 %7, i1 true, i1 %8
@@ -113,21 +152,30 @@ define i32 @cmp_or3(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5) {
113152

114153
; (x0 < x1) || (x2 > x3) || (x4 != x5) || (x6 == x7)
115154
define i32 @cmp_or4(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7) {
116-
; CHECK-LABEL: cmp_or4:
117-
; CHECK: // %bb.0:
118-
; CHECK-NEXT: cmp w0, w1
119-
; CHECK-NEXT: cset w8, lo
120-
; CHECK-NEXT: cmp w2, w3
121-
; CHECK-NEXT: cset w9, hi
122-
; CHECK-NEXT: cmp w4, w5
123-
; CHECK-NEXT: cset w10, ne
124-
; CHECK-NEXT: cmp w6, w7
125-
; CHECK-NEXT: orr w8, w8, w9
126-
; CHECK-NEXT: cset w11, eq
127-
; CHECK-NEXT: orr w9, w10, w11
128-
; CHECK-NEXT: orr w8, w8, w9
129-
; CHECK-NEXT: and w0, w8, #0x1
130-
; CHECK-NEXT: ret
155+
; SDISEL-LABEL: cmp_or4:
156+
; SDISEL: // %bb.0:
157+
; SDISEL-NEXT: cmp w0, w1
158+
; SDISEL-NEXT: ccmp w2, w3, #2, hs
159+
; SDISEL-NEXT: ccmp w4, w5, #0, ls
160+
; SDISEL-NEXT: ccmp w6, w7, #4, eq
161+
; SDISEL-NEXT: cset w0, eq
162+
; SDISEL-NEXT: ret
163+
;
164+
; GISEL-LABEL: cmp_or4:
165+
; GISEL: // %bb.0:
166+
; GISEL-NEXT: cmp w0, w1
167+
; GISEL-NEXT: cset w8, lo
168+
; GISEL-NEXT: cmp w2, w3
169+
; GISEL-NEXT: cset w9, hi
170+
; GISEL-NEXT: cmp w4, w5
171+
; GISEL-NEXT: cset w10, ne
172+
; GISEL-NEXT: cmp w6, w7
173+
; GISEL-NEXT: orr w8, w8, w9
174+
; GISEL-NEXT: cset w11, eq
175+
; GISEL-NEXT: orr w9, w10, w11
176+
; GISEL-NEXT: orr w8, w8, w9
177+
; GISEL-NEXT: and w0, w8, #0x1
178+
; GISEL-NEXT: ret
131179
%9 = icmp ult i32 %0, %1
132180
%10 = icmp ugt i32 %2, %3
133181
%11 = select i1 %9, i1 true, i1 %10
@@ -194,3 +242,5 @@ define i32 @true_or3(i32 %0, i32 %1, i32 %2) {
194242
%9 = zext i1 %8 to i32
195243
ret i32 %9
196244
}
245+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
246+
; CHECK: {{.*}}

llvm/test/CodeGen/AArch64/select-with-and-or.ll

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ define i1 @and(i32 %x, i32 %y, i32 %z, i32 %w) {
55
; CHECK-LABEL: and:
66
; CHECK: // %bb.0:
77
; CHECK-NEXT: cmp w0, w1
8-
; CHECK-NEXT: cset w8, eq
9-
; CHECK-NEXT: cmp w2, w3
10-
; CHECK-NEXT: cset w9, gt
11-
; CHECK-NEXT: and w0, w8, w9
8+
; CHECK-NEXT: ccmp w2, w3, #4, eq
9+
; CHECK-NEXT: cset w0, gt
1210
; CHECK-NEXT: ret
1311
%a = icmp eq i32 %x, %y
1412
%b = icmp sgt i32 %z, %w
@@ -20,11 +18,8 @@ define i1 @or(i32 %x, i32 %y, i32 %z, i32 %w) {
2018
; CHECK-LABEL: or:
2119
; CHECK: // %bb.0:
2220
; CHECK-NEXT: cmp w0, w1
23-
; CHECK-NEXT: cset w8, eq
24-
; CHECK-NEXT: cmp w2, w3
25-
; CHECK-NEXT: cset w9, gt
26-
; CHECK-NEXT: orr w8, w8, w9
27-
; CHECK-NEXT: and w0, w8, #0x1
21+
; CHECK-NEXT: ccmp w2, w3, #0, ne
22+
; CHECK-NEXT: cset w0, gt
2823
; CHECK-NEXT: ret
2924
%a = icmp eq i32 %x, %y
3025
%b = icmp sgt i32 %z, %w
@@ -36,10 +31,8 @@ define i1 @and_not(i32 %x, i32 %y, i32 %z, i32 %w) {
3631
; CHECK-LABEL: and_not:
3732
; CHECK: // %bb.0:
3833
; CHECK-NEXT: cmp w0, w1
39-
; CHECK-NEXT: cset w8, ne
40-
; CHECK-NEXT: cmp w2, w3
41-
; CHECK-NEXT: cset w9, gt
42-
; CHECK-NEXT: and w0, w8, w9
34+
; CHECK-NEXT: ccmp w2, w3, #4, ne
35+
; CHECK-NEXT: cset w0, gt
4336
; CHECK-NEXT: ret
4437
%a = icmp eq i32 %x, %y
4538
%b = icmp sgt i32 %z, %w
@@ -51,11 +44,8 @@ define i1 @or_not(i32 %x, i32 %y, i32 %z, i32 %w) {
5144
; CHECK-LABEL: or_not:
5245
; CHECK: // %bb.0:
5346
; CHECK-NEXT: cmp w0, w1
54-
; CHECK-NEXT: cset w8, ne
55-
; CHECK-NEXT: cmp w2, w3
56-
; CHECK-NEXT: cset w9, gt
57-
; CHECK-NEXT: orr w8, w8, w9
58-
; CHECK-NEXT: and w0, w8, #0x1
47+
; CHECK-NEXT: ccmp w2, w3, #0, eq
48+
; CHECK-NEXT: cset w0, gt
5949
; CHECK-NEXT: ret
6050
%a = icmp eq i32 %x, %y
6151
%b = icmp sgt i32 %z, %w

llvm/test/CodeGen/PowerPC/pr40922.ll

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ define i32 @a() {
2323
; CHECK-NEXT: li 5, 0
2424
; CHECK-NEXT: mr 30, 3
2525
; CHECK-NEXT: addic 6, 4, 6
26-
; CHECK-NEXT: rlwinm 6, 6, 0, 28, 26
2726
; CHECK-NEXT: addze 5, 5
28-
; CHECK-NEXT: cmplw 1, 6, 4
27+
; CHECK-NEXT: rlwinm 6, 6, 0, 28, 26
2928
; CHECK-NEXT: andi. 5, 5, 1
30-
; CHECK-NEXT: crnot 20, 4
31-
; CHECK-NEXT: cror 20, 1, 20
29+
; CHECK-NEXT: cmplw 1, 6, 4
30+
; CHECK-NEXT: crorc 20, 1, 4
3231
; CHECK-NEXT: bc 12, 20, .LBB0_2
3332
; CHECK-NEXT: # %bb.1: # %if.then
3433
; CHECK-NEXT: bl e

0 commit comments

Comments
 (0)