Skip to content

Commit d8e50c9

Browse files
committed
[CodeGen] Add PR50197 AArch64/ARM/X86 test coverage
Pre-commit for D111530
1 parent 74cd4de commit d8e50c9

File tree

3 files changed

+627
-0
lines changed

3 files changed

+627
-0
lines changed
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
3+
4+
; Optimize expanded SRL/SHL used as an input of
5+
; SETCC comparing it with zero by removing rotation.
6+
;
7+
; See https://bugs.llvm.org/show_bug.cgi?id=50197
8+
define i128 @opt_setcc_lt_power_of_2(i128 %a) nounwind {
9+
; CHECK-LABEL: opt_setcc_lt_power_of_2:
10+
; CHECK: // %bb.0:
11+
; CHECK-NEXT: .LBB0_1: // %loop
12+
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
13+
; CHECK-NEXT: adds x0, x0, #1
14+
; CHECK-NEXT: adcs x1, x1, xzr
15+
; CHECK-NEXT: extr x8, x1, x0, #60
16+
; CHECK-NEXT: orr x8, x8, x1, lsr #60
17+
; CHECK-NEXT: cbnz x8, .LBB0_1
18+
; CHECK-NEXT: // %bb.2: // %exit
19+
; CHECK-NEXT: ret
20+
br label %loop
21+
22+
loop:
23+
%phi.a = phi i128 [ %a, %0 ], [ %inc, %loop ]
24+
%inc = add i128 %phi.a, 1
25+
%cmp = icmp ult i128 %inc, 1152921504606846976
26+
br i1 %cmp, label %exit, label %loop
27+
28+
exit:
29+
ret i128 %inc
30+
}
31+
32+
define i1 @opt_setcc_srl_eq_zero(i128 %a) nounwind {
33+
; CHECK-LABEL: opt_setcc_srl_eq_zero:
34+
; CHECK: // %bb.0:
35+
; CHECK-NEXT: extr x8, x1, x0, #17
36+
; CHECK-NEXT: orr x8, x8, x1, lsr #17
37+
; CHECK-NEXT: cmp x8, #0
38+
; CHECK-NEXT: cset w0, eq
39+
; CHECK-NEXT: ret
40+
%srl = lshr i128 %a, 17
41+
%cmp = icmp eq i128 %srl, 0
42+
ret i1 %cmp
43+
}
44+
45+
define i1 @opt_setcc_srl_ne_zero(i128 %a) nounwind {
46+
; CHECK-LABEL: opt_setcc_srl_ne_zero:
47+
; CHECK: // %bb.0:
48+
; CHECK-NEXT: extr x8, x1, x0, #17
49+
; CHECK-NEXT: orr x8, x8, x1, lsr #17
50+
; CHECK-NEXT: cmp x8, #0
51+
; CHECK-NEXT: cset w0, ne
52+
; CHECK-NEXT: ret
53+
%srl = lshr i128 %a, 17
54+
%cmp = icmp ne i128 %srl, 0
55+
ret i1 %cmp
56+
}
57+
58+
define i1 @opt_setcc_shl_eq_zero(i128 %a) nounwind {
59+
; CHECK-LABEL: opt_setcc_shl_eq_zero:
60+
; CHECK: // %bb.0:
61+
; CHECK-NEXT: extr x8, x1, x0, #47
62+
; CHECK-NEXT: orr x8, x8, x0, lsl #17
63+
; CHECK-NEXT: cmp x8, #0
64+
; CHECK-NEXT: cset w0, eq
65+
; CHECK-NEXT: ret
66+
%shl = shl i128 %a, 17
67+
%cmp = icmp eq i128 %shl, 0
68+
ret i1 %cmp
69+
}
70+
71+
define i1 @opt_setcc_shl_ne_zero(i128 %a) nounwind {
72+
; CHECK-LABEL: opt_setcc_shl_ne_zero:
73+
; CHECK: // %bb.0:
74+
; CHECK-NEXT: extr x8, x1, x0, #47
75+
; CHECK-NEXT: orr x8, x8, x0, lsl #17
76+
; CHECK-NEXT: cmp x8, #0
77+
; CHECK-NEXT: cset w0, ne
78+
; CHECK-NEXT: ret
79+
%shl = shl i128 %a, 17
80+
%cmp = icmp ne i128 %shl, 0
81+
ret i1 %cmp
82+
}
83+
84+
; Negative test: optimization should not be applied if shift has multiple users.
85+
define i1 @opt_setcc_shl_eq_zero_multiple_shl_users(i128 %a) nounwind {
86+
; CHECK-LABEL: opt_setcc_shl_eq_zero_multiple_shl_users:
87+
; CHECK: // %bb.0:
88+
; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
89+
; CHECK-NEXT: extr x1, x1, x0, #47
90+
; CHECK-NEXT: lsl x0, x0, #17
91+
; CHECK-NEXT: orr x8, x0, x1
92+
; CHECK-NEXT: cmp x8, #0
93+
; CHECK-NEXT: cset w19, eq
94+
; CHECK-NEXT: bl use
95+
; CHECK-NEXT: mov w0, w19
96+
; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
97+
; CHECK-NEXT: ret
98+
%shl = shl i128 %a, 17
99+
%cmp = icmp eq i128 %shl, 0
100+
call void @use(i128 %shl)
101+
ret i1 %cmp
102+
}
103+
104+
; Check that optimization is applied to DAG having appropriate shape
105+
; even if there were no actual shift's expansion.
106+
define i1 @opt_setcc_expanded_shl_correct_shifts(i64 %a, i64 %b) nounwind {
107+
; CHECK-LABEL: opt_setcc_expanded_shl_correct_shifts:
108+
; CHECK: // %bb.0:
109+
; CHECK-NEXT: extr x8, x0, x1, #47
110+
; CHECK-NEXT: orr x8, x8, x1, lsl #17
111+
; CHECK-NEXT: cmp x8, #0
112+
; CHECK-NEXT: cset w0, eq
113+
; CHECK-NEXT: ret
114+
%shl.a = shl i64 %a, 17
115+
%srl.b = lshr i64 %b, 47
116+
%or.0 = or i64 %shl.a, %srl.b
117+
%shl.b = shl i64 %b, 17
118+
%or.1 = or i64 %or.0, %shl.b
119+
%cmp = icmp eq i64 %or.1, 0
120+
ret i1 %cmp
121+
}
122+
123+
; Negative test: optimization should not be applied as
124+
; constants used in shifts do not match.
125+
define i1 @opt_setcc_expanded_shl_wrong_shifts(i64 %a, i64 %b) nounwind {
126+
; CHECK-LABEL: opt_setcc_expanded_shl_wrong_shifts:
127+
; CHECK: // %bb.0:
128+
; CHECK-NEXT: extr x8, x0, x1, #47
129+
; CHECK-NEXT: orr x8, x8, x1, lsl #18
130+
; CHECK-NEXT: cmp x8, #0
131+
; CHECK-NEXT: cset w0, eq
132+
; CHECK-NEXT: ret
133+
%shl.a = shl i64 %a, 17
134+
%srl.b = lshr i64 %b, 47
135+
%or.0 = or i64 %shl.a, %srl.b
136+
%shl.b = shl i64 %b, 18
137+
%or.1 = or i64 %or.0, %shl.b
138+
%cmp = icmp eq i64 %or.1, 0
139+
ret i1 %cmp
140+
}
141+
142+
declare void @use(i128 %a)
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=armv7 %s -o - | FileCheck %s
3+
4+
; Optimize expanded SRL/SHL used as an input of
5+
; SETCC comparing it with zero by removing rotation.
6+
;
7+
; See https://bugs.llvm.org/show_bug.cgi?id=50197
8+
define i64 @opt_setcc_lt_power_of_2(i64 %a) nounwind {
9+
; CHECK-LABEL: opt_setcc_lt_power_of_2:
10+
; CHECK: @ %bb.0:
11+
; CHECK-NEXT: .LBB0_1: @ %loop
12+
; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1
13+
; CHECK-NEXT: adds r0, r0, #1
14+
; CHECK-NEXT: adc r1, r1, #0
15+
; CHECK-NEXT: lsr r2, r0, #16
16+
; CHECK-NEXT: orr r2, r2, r1, lsl #16
17+
; CHECK-NEXT: orr r2, r2, r1, lsr #16
18+
; CHECK-NEXT: cmp r2, #0
19+
; CHECK-NEXT: bne .LBB0_1
20+
; CHECK-NEXT: @ %bb.2: @ %exit
21+
; CHECK-NEXT: bx lr
22+
br label %loop
23+
24+
loop:
25+
%phi.a = phi i64 [ %a, %0 ], [ %inc, %loop ]
26+
%inc = add i64 %phi.a, 1
27+
%cmp = icmp ult i64 %inc, 65536
28+
br i1 %cmp, label %exit, label %loop
29+
30+
exit:
31+
ret i64 %inc
32+
}
33+
34+
define i1 @opt_setcc_srl_eq_zero(i64 %a) nounwind {
35+
; CHECK-LABEL: opt_setcc_srl_eq_zero:
36+
; CHECK: @ %bb.0:
37+
; CHECK-NEXT: lsr r0, r0, #17
38+
; CHECK-NEXT: orr r0, r0, r1, lsl #15
39+
; CHECK-NEXT: orr r0, r0, r1, lsr #17
40+
; CHECK-NEXT: clz r0, r0
41+
; CHECK-NEXT: lsr r0, r0, #5
42+
; CHECK-NEXT: bx lr
43+
%srl = lshr i64 %a, 17
44+
%cmp = icmp eq i64 %srl, 0
45+
ret i1 %cmp
46+
}
47+
48+
define i1 @opt_setcc_srl_ne_zero(i64 %a) nounwind {
49+
; CHECK-LABEL: opt_setcc_srl_ne_zero:
50+
; CHECK: @ %bb.0:
51+
; CHECK-NEXT: lsr r0, r0, #17
52+
; CHECK-NEXT: orr r0, r0, r1, lsl #15
53+
; CHECK-NEXT: orr r0, r0, r1, lsr #17
54+
; CHECK-NEXT: cmp r0, #0
55+
; CHECK-NEXT: movwne r0, #1
56+
; CHECK-NEXT: bx lr
57+
%srl = lshr i64 %a, 17
58+
%cmp = icmp ne i64 %srl, 0
59+
ret i1 %cmp
60+
}
61+
62+
define i1 @opt_setcc_shl_eq_zero(i64 %a) nounwind {
63+
; CHECK-LABEL: opt_setcc_shl_eq_zero:
64+
; CHECK: @ %bb.0:
65+
; CHECK-NEXT: lsl r1, r1, #17
66+
; CHECK-NEXT: orr r1, r1, r0, lsr #15
67+
; CHECK-NEXT: orr r0, r1, r0, lsl #17
68+
; CHECK-NEXT: clz r0, r0
69+
; CHECK-NEXT: lsr r0, r0, #5
70+
; CHECK-NEXT: bx lr
71+
%shl = shl i64 %a, 17
72+
%cmp = icmp eq i64 %shl, 0
73+
ret i1 %cmp
74+
}
75+
76+
define i1 @opt_setcc_shl_ne_zero(i64 %a) nounwind {
77+
; CHECK-LABEL: opt_setcc_shl_ne_zero:
78+
; CHECK: @ %bb.0:
79+
; CHECK-NEXT: lsl r1, r1, #17
80+
; CHECK-NEXT: orr r1, r1, r0, lsr #15
81+
; CHECK-NEXT: orr r0, r1, r0, lsl #17
82+
; CHECK-NEXT: cmp r0, #0
83+
; CHECK-NEXT: movwne r0, #1
84+
; CHECK-NEXT: bx lr
85+
%shl = shl i64 %a, 17
86+
%cmp = icmp ne i64 %shl, 0
87+
ret i1 %cmp
88+
}
89+
90+
; Negative test: optimization should not be applied if shift has multiple users.
91+
define i1 @opt_setcc_shl_eq_zero_multiple_shl_users(i64 %a) nounwind {
92+
; CHECK-LABEL: opt_setcc_shl_eq_zero_multiple_shl_users:
93+
; CHECK: @ %bb.0:
94+
; CHECK-NEXT: push {r4, r5, r11, lr}
95+
; CHECK-NEXT: mov r4, r0
96+
; CHECK-NEXT: lsl r0, r1, #17
97+
; CHECK-NEXT: orr r5, r0, r4, lsr #15
98+
; CHECK-NEXT: lsl r0, r4, #17
99+
; CHECK-NEXT: mov r1, r5
100+
; CHECK-NEXT: bl use
101+
; CHECK-NEXT: orr r0, r5, r4, lsl #17
102+
; CHECK-NEXT: clz r0, r0
103+
; CHECK-NEXT: lsr r0, r0, #5
104+
; CHECK-NEXT: pop {r4, r5, r11, pc}
105+
%shl = shl i64 %a, 17
106+
%cmp = icmp eq i64 %shl, 0
107+
call void @use(i64 %shl)
108+
ret i1 %cmp
109+
}
110+
111+
; Check that optimization is applied to DAG having appropriate shape
112+
; even if there were no actual shift's expansion.
113+
define i1 @opt_setcc_expanded_shl_correct_shifts(i32 %a, i32 %b) nounwind {
114+
; CHECK-LABEL: opt_setcc_expanded_shl_correct_shifts:
115+
; CHECK: @ %bb.0:
116+
; CHECK-NEXT: lsl r0, r0, #17
117+
; CHECK-NEXT: orr r0, r0, r1, lsr #15
118+
; CHECK-NEXT: orr r0, r0, r1, lsl #17
119+
; CHECK-NEXT: clz r0, r0
120+
; CHECK-NEXT: lsr r0, r0, #5
121+
; CHECK-NEXT: bx lr
122+
%shl.a = shl i32 %a, 17
123+
%srl.b = lshr i32 %b, 15
124+
%or.0 = or i32 %shl.a, %srl.b
125+
%shl.b = shl i32 %b, 17
126+
%or.1 = or i32 %or.0, %shl.b
127+
%cmp = icmp eq i32 %or.1, 0
128+
ret i1 %cmp
129+
}
130+
131+
; Negative test: optimization should not be applied as
132+
; constants used in shifts do not match.
133+
define i1 @opt_setcc_expanded_shl_wrong_shifts(i32 %a, i32 %b) nounwind {
134+
; CHECK-LABEL: opt_setcc_expanded_shl_wrong_shifts:
135+
; CHECK: @ %bb.0:
136+
; CHECK-NEXT: lsl r0, r0, #17
137+
; CHECK-NEXT: orr r0, r0, r1, lsr #15
138+
; CHECK-NEXT: orr r0, r0, r1, lsl #18
139+
; CHECK-NEXT: clz r0, r0
140+
; CHECK-NEXT: lsr r0, r0, #5
141+
; CHECK-NEXT: bx lr
142+
%shl.a = shl i32 %a, 17
143+
%srl.b = lshr i32 %b, 15
144+
%or.0 = or i32 %shl.a, %srl.b
145+
%shl.b = shl i32 %b, 18
146+
%or.1 = or i32 %or.0, %shl.b
147+
%cmp = icmp eq i32 %or.1, 0
148+
ret i1 %cmp
149+
}
150+
151+
declare void @use(i64 %a)

0 commit comments

Comments
 (0)