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