xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/fcvt_combine.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-neon-syntax=apple -verify-machineinstrs -o - %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test1
4*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.2s
5*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2s v0, v0, #4
6*9880d681SAndroid Build Coastguard Worker; CHECK: ret
7*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test1(<2 x float> %f) {
8*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 16.000000e+00, float 16.000000e+00>
9*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i32>
10*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
11*9880d681SAndroid Build Coastguard Worker}
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2
14*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.4s
15*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.4s v0, v0, #3
16*9880d681SAndroid Build Coastguard Worker; CHECK: ret
17*9880d681SAndroid Build Coastguard Workerdefine <4 x i32> @test2(<4 x float> %f) {
18*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <4 x float> %f, <float 8.000000e+00, float 8.000000e+00, float 8.000000e+00, float 8.000000e+00>
19*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <4 x float> %mul.i to <4 x i32>
20*9880d681SAndroid Build Coastguard Worker  ret <4 x i32> %vcvt.i
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3
24*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.2d
25*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2d v0, v0, #5
26*9880d681SAndroid Build Coastguard Worker; CHECK: ret
27*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test3(<2 x double> %d) {
28*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x double> %d, <double 32.000000e+00, double 32.000000e+00>
29*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x double> %mul.i to <2 x i64>
30*9880d681SAndroid Build Coastguard Worker  ret <2 x i64> %vcvt.i
31*9880d681SAndroid Build Coastguard Worker}
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker; Truncate double to i32
34*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4
35*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.2d v0, v0, #4
36*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2d v0, v0
37*9880d681SAndroid Build Coastguard Worker; CHECK: xtn.2s
38*9880d681SAndroid Build Coastguard Worker; CHECK: ret
39*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test4(<2 x double> %d) {
40*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x double> %d, <double 16.000000e+00, double 16.000000e+00>
41*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x double> %mul.i to <2 x i32>
42*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker; Truncate float to i16
46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test5
47*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.2s
48*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2s v0, v0, #4
49*9880d681SAndroid Build Coastguard Worker; CHECK: ret
50*9880d681SAndroid Build Coastguard Workerdefine <2 x i16> @test5(<2 x float> %f) {
51*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 16.000000e+00, float 16.000000e+00>
52*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i16>
53*9880d681SAndroid Build Coastguard Worker  ret <2 x i16> %vcvt.i
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker; Don't convert float to i64
57*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test6
58*9880d681SAndroid Build Coastguard Worker; CHECK: fmov.2s v1, #16.00000000
59*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v0, v0, v1
60*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtl v0.2d, v0.2s
61*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2d v0, v0
62*9880d681SAndroid Build Coastguard Worker; CHECK: ret
63*9880d681SAndroid Build Coastguard Workerdefine <2 x i64> @test6(<2 x float> %f) {
64*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 16.000000e+00, float 16.000000e+00>
65*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i64>
66*9880d681SAndroid Build Coastguard Worker  ret <2 x i64> %vcvt.i
67*9880d681SAndroid Build Coastguard Worker}
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker; Check unsigned conversion.
70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test7
71*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: fmul.2s
72*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzu.2s v0, v0, #4
73*9880d681SAndroid Build Coastguard Worker; CHECK: ret
74*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test7(<2 x float> %f) {
75*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 16.000000e+00, float 16.000000e+00>
76*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptoui <2 x float> %mul.i to <2 x i32>
77*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
78*9880d681SAndroid Build Coastguard Worker}
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker; Test which should not fold due to non-power of 2.
81*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test8
82*9880d681SAndroid Build Coastguard Worker; CHECK: fmov.2s v1, #17.00000000
83*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v0, v0, v1
84*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzu.2s v0, v0
85*9880d681SAndroid Build Coastguard Worker; CHECK: ret
86*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test8(<2 x float> %f) {
87*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 17.000000e+00, float 17.000000e+00>
88*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptoui <2 x float> %mul.i to <2 x i32>
89*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
90*9880d681SAndroid Build Coastguard Worker}
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker; Test which should not fold due to non-matching power of 2.
93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test9
94*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v0, v0, v1
95*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzu.2s v0, v0
96*9880d681SAndroid Build Coastguard Worker; CHECK: ret
97*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test9(<2 x float> %f) {
98*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 16.000000e+00, float 8.000000e+00>
99*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptoui <2 x float> %mul.i to <2 x i32>
100*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker; Don't combine all undefs.
104*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test10
105*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
106*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzu.2s v{{[0-9]+}}, v{{[0-9]+}}
107*9880d681SAndroid Build Coastguard Worker; CHECK: ret
108*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test10(<2 x float> %f) {
109*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float undef, float undef>
110*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptoui <2 x float> %mul.i to <2 x i32>
111*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
112*9880d681SAndroid Build Coastguard Worker}
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker; Combine if mix of undef and pow2.
115*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test11
116*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzu.2s v0, v0, #3
117*9880d681SAndroid Build Coastguard Worker; CHECK: ret
118*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test11(<2 x float> %f) {
119*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float undef, float 8.000000e+00>
120*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptoui <2 x float> %mul.i to <2 x i32>
121*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker; Don't combine when multiplied by 0.0.
125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test12
126*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v0, v0, v1
127*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2s v0, v0
128*9880d681SAndroid Build Coastguard Worker; CHECK: ret
129*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test12(<2 x float> %f) {
130*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 0.000000e+00, float 0.000000e+00>
131*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i32>
132*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
133*9880d681SAndroid Build Coastguard Worker}
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker; Test which should not fold due to power of 2 out of range (i.e., 2^33).
136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test13
137*9880d681SAndroid Build Coastguard Worker; CHECK: fmul.2s v0, v0, v1
138*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2s v0, v0
139*9880d681SAndroid Build Coastguard Worker; CHECK: ret
140*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test13(<2 x float> %f) {
141*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 0x4200000000000000, float 0x4200000000000000>
142*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i32>
143*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; Test case where const is max power of 2 (i.e., 2^32).
147*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test14
148*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.2s v0, v0, #32
149*9880d681SAndroid Build Coastguard Worker; CHECK: ret
150*9880d681SAndroid Build Coastguard Workerdefine <2 x i32> @test14(<2 x float> %f) {
151*9880d681SAndroid Build Coastguard Worker  %mul.i = fmul <2 x float> %f, <float 0x41F0000000000000, float 0x41F0000000000000>
152*9880d681SAndroid Build Coastguard Worker  %vcvt.i = fptosi <2 x float> %mul.i to <2 x i32>
153*9880d681SAndroid Build Coastguard Worker  ret <2 x i32> %vcvt.i
154*9880d681SAndroid Build Coastguard Worker}
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_illegal_fp_to_int:
157*9880d681SAndroid Build Coastguard Worker; CHECK: fcvtzs.4s v0, v0, #2
158*9880d681SAndroid Build Coastguard Workerdefine <3 x i32> @test_illegal_fp_to_int(<3 x float> %in) {
159*9880d681SAndroid Build Coastguard Worker  %scale = fmul <3 x float> %in, <float 4.0, float 4.0, float 4.0>
160*9880d681SAndroid Build Coastguard Worker  %val = fptosi <3 x float> %scale to <3 x i32>
161*9880d681SAndroid Build Coastguard Worker  ret <3 x i32> %val
162*9880d681SAndroid Build Coastguard Worker}
163