Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 3a2e78e

Browse files
committed
[DAGCombiner] Add rotate-extract tests
Add new tests from D47681 to current codegen. Also added i686 codegen tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337445 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent cfc3a3c commit 3a2e78e

File tree

3 files changed

+750
-0
lines changed

3 files changed

+750
-0
lines changed
+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s
3+
4+
; Check that under certain conditions we can factor out a rotate
5+
; from the following idioms:
6+
; (a*c0) >> s1 | (a*c1)
7+
; (a/c0) << s1 | (a/c1)
8+
; This targets cases where instcombine has folded a shl/srl/mul/udiv
9+
; with one of the shifts from the rotate idiom
10+
11+
define i64 @ror_extract_shl(i64 %i) nounwind {
12+
; CHECK-LABEL: ror_extract_shl:
13+
; CHECK: // %bb.0:
14+
; CHECK-NEXT: lsl x8, x0, #10
15+
; CHECK-NEXT: bfxil x8, x0, #54, #7
16+
; CHECK-NEXT: mov x0, x8
17+
; CHECK-NEXT: ret
18+
%lhs_mul = shl i64 %i, 3
19+
%rhs_mul = shl i64 %i, 10
20+
%lhs_shift = lshr i64 %lhs_mul, 57
21+
%out = or i64 %lhs_shift, %rhs_mul
22+
ret i64 %out
23+
}
24+
25+
define i32 @ror_extract_shrl(i32 %i) nounwind {
26+
; CHECK-LABEL: ror_extract_shrl:
27+
; CHECK: // %bb.0:
28+
; CHECK-NEXT: ror w8, w0, #7
29+
; CHECK-NEXT: and w0, w8, #0xf1ffffff
30+
; CHECK-NEXT: ret
31+
%lhs_div = lshr i32 %i, 7
32+
%rhs_div = lshr i32 %i, 3
33+
%rhs_shift = shl i32 %rhs_div, 28
34+
%out = or i32 %lhs_div, %rhs_shift
35+
ret i32 %out
36+
}
37+
38+
define i32 @ror_extract_mul(i32 %i) nounwind {
39+
; CHECK-LABEL: ror_extract_mul:
40+
; CHECK: // %bb.0:
41+
; CHECK-NEXT: add w8, w0, w0, lsl #3
42+
; CHECK-NEXT: ror w0, w8, #25
43+
; CHECK-NEXT: ret
44+
%lhs_mul = mul i32 %i, 9
45+
%rhs_mul = mul i32 %i, 1152
46+
%lhs_shift = lshr i32 %lhs_mul, 25
47+
%out = or i32 %lhs_shift, %rhs_mul
48+
ret i32 %out
49+
}
50+
51+
define i64 @ror_extract_udiv(i64 %i) nounwind {
52+
; CHECK-LABEL: ror_extract_udiv:
53+
; CHECK: // %bb.0:
54+
; CHECK-NEXT: mov x8, #-6148914691236517206
55+
; CHECK-NEXT: movk x8, #43691
56+
; CHECK-NEXT: umulh x8, x0, x8
57+
; CHECK-NEXT: ror x8, x8, #5
58+
; CHECK-NEXT: and x0, x8, #0xf7ffffffffffffff
59+
; CHECK-NEXT: ret
60+
%lhs_div = udiv i64 %i, 3
61+
%rhs_div = udiv i64 %i, 48
62+
%lhs_shift = shl i64 %lhs_div, 60
63+
%out = or i64 %lhs_shift, %rhs_div
64+
ret i64 %out
65+
}
66+
67+
define i64 @ror_extract_mul_with_mask(i64 %i) nounwind {
68+
; CHECK-LABEL: ror_extract_mul_with_mask:
69+
; CHECK: // %bb.0:
70+
; CHECK-NEXT: add w8, w0, w0, lsl #3
71+
; CHECK-NEXT: lsl w8, w8, #7
72+
; CHECK-NEXT: add x9, x0, x0, lsl #3
73+
; CHECK-NEXT: and x0, x8, #0x80
74+
; CHECK-NEXT: bfxil x0, x9, #57, #7
75+
; CHECK-NEXT: ret
76+
%lhs_mul = mul i64 %i, 1152
77+
%rhs_mul = mul i64 %i, 9
78+
%lhs_and = and i64 %lhs_mul, 160
79+
%rhs_shift = lshr i64 %rhs_mul, 57
80+
%out = or i64 %lhs_and, %rhs_shift
81+
ret i64 %out
82+
}
83+
84+
; Result would undershift
85+
define i64 @no_extract_shl(i64 %i) nounwind {
86+
; CHECK-LABEL: no_extract_shl:
87+
; CHECK: // %bb.0:
88+
; CHECK-NEXT: lsl x8, x0, #10
89+
; CHECK-NEXT: bfxil x8, x0, #52, #7
90+
; CHECK-NEXT: mov x0, x8
91+
; CHECK-NEXT: ret
92+
%lhs_mul = shl i64 %i, 5
93+
%rhs_mul = shl i64 %i, 10
94+
%lhs_shift = lshr i64 %lhs_mul, 57
95+
%out = or i64 %lhs_shift, %rhs_mul
96+
ret i64 %out
97+
}
98+
99+
; Result would overshift
100+
define i32 @no_extract_shrl(i32 %i) nounwind {
101+
; CHECK-LABEL: no_extract_shrl:
102+
; CHECK: // %bb.0:
103+
; CHECK-NEXT: lsr w8, w0, #3
104+
; CHECK-NEXT: lsr w0, w0, #9
105+
; CHECK-NEXT: bfi w0, w8, #28, #4
106+
; CHECK-NEXT: ret
107+
%lhs_div = lshr i32 %i, 3
108+
%rhs_div = lshr i32 %i, 9
109+
%lhs_shift = shl i32 %lhs_div, 28
110+
%out = or i32 %lhs_shift, %rhs_div
111+
ret i32 %out
112+
}
113+
114+
; Can factor 128 from 2304, but result is 18 instead of 9
115+
define i64 @no_extract_mul(i64 %i) nounwind {
116+
; CHECK-LABEL: no_extract_mul:
117+
; CHECK: // %bb.0:
118+
; CHECK-NEXT: add x8, x0, x0, lsl #3
119+
; CHECK-NEXT: lsr x0, x8, #57
120+
; CHECK-NEXT: bfi x0, x8, #8, #56
121+
; CHECK-NEXT: ret
122+
%lhs_mul = mul i64 %i, 2304
123+
%rhs_mul = mul i64 %i, 9
124+
%rhs_shift = lshr i64 %rhs_mul, 57
125+
%out = or i64 %lhs_mul, %rhs_shift
126+
ret i64 %out
127+
}
128+
129+
; Can't evenly factor 16 from 49
130+
define i32 @no_extract_udiv(i32 %i) nounwind {
131+
; CHECK-LABEL: no_extract_udiv:
132+
; CHECK: // %bb.0:
133+
; CHECK-NEXT: mov w8, #43691
134+
; CHECK-NEXT: mov w9, #33437
135+
; CHECK-NEXT: movk w8, #43690, lsl #16
136+
; CHECK-NEXT: movk w9, #21399, lsl #16
137+
; CHECK-NEXT: umull x8, w0, w8
138+
; CHECK-NEXT: umull x9, w0, w9
139+
; CHECK-NEXT: lsr x8, x8, #33
140+
; CHECK-NEXT: lsr x9, x9, #32
141+
; CHECK-NEXT: extr w0, w8, w9, #4
142+
; CHECK-NEXT: ret
143+
%lhs_div = udiv i32 %i, 3
144+
%rhs_div = udiv i32 %i, 49
145+
%lhs_shift = shl i32 %lhs_div, 28
146+
%out = or i32 %lhs_shift, %rhs_div
147+
ret i32 %out
148+
}

0 commit comments

Comments
 (0)