1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-unknown-unknown -march=x86-64 < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul2_f32: 4*9880d681SAndroid Build Coastguard Worker; CHECK: addss %xmm0, %xmm0 5*9880d681SAndroid Build Coastguard Workerdefine float @fmul2_f32(float %x) { 6*9880d681SAndroid Build Coastguard Worker %y = fmul float %x, 2.0 7*9880d681SAndroid Build Coastguard Worker ret float %y 8*9880d681SAndroid Build Coastguard Worker} 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; fmul 2.0, x -> fadd x, x for vectors. 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul2_v4f32: 13*9880d681SAndroid Build Coastguard Worker; CHECK: addps %xmm0, %xmm0 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 15*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul2_v4f32(<4 x float> %x) { 16*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0> 17*9880d681SAndroid Build Coastguard Worker ret <4 x float> %y 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: constant_fold_fmul_v4f32: 21*9880d681SAndroid Build Coastguard Worker; CHECK: movaps 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 23*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @constant_fold_fmul_v4f32(<4 x float> %x) { 24*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> <float 4.0, float 4.0, float 4.0, float 4.0>, <float 2.0, float 2.0, float 2.0, float 2.0> 25*9880d681SAndroid Build Coastguard Worker ret <4 x float> %y 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul0_v4f32: 29*9880d681SAndroid Build Coastguard Worker; CHECK: xorps %xmm0, %xmm0 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 31*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul0_v4f32(<4 x float> %x) #0 { 32*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 0.0, float 0.0, float 0.0, float 0.0> 33*9880d681SAndroid Build Coastguard Worker ret <4 x float> %y 34*9880d681SAndroid Build Coastguard Worker} 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c2_c4_v4f32: 37*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addps 38*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 39*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 41*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_c2_c4_v4f32(<4 x float> %x) #0 { 42*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0> 43*9880d681SAndroid Build Coastguard Worker %z = fmul <4 x float> %y, <float 4.0, float 4.0, float 4.0, float 4.0> 44*9880d681SAndroid Build Coastguard Worker ret <4 x float> %z 45*9880d681SAndroid Build Coastguard Worker} 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c3_c4_v4f32: 48*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addps 49*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 50*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps 51*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 52*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_c3_c4_v4f32(<4 x float> %x) #0 { 53*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 3.0, float 3.0, float 3.0, float 3.0> 54*9880d681SAndroid Build Coastguard Worker %z = fmul <4 x float> %y, <float 4.0, float 4.0, float 4.0, float 4.0> 55*9880d681SAndroid Build Coastguard Worker ret <4 x float> %z 56*9880d681SAndroid Build Coastguard Worker} 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; We should be able to pre-multiply the two constant vectors. 59*9880d681SAndroid Build Coastguard Worker; CHECK: float 5 60*9880d681SAndroid Build Coastguard Worker; CHECK: float 12 61*9880d681SAndroid Build Coastguard Worker; CHECK: float 21 62*9880d681SAndroid Build Coastguard Worker; CHECK: float 32 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat: 64*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps 66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 67*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat(<4 x float> %x) #0 { 68*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 69*9880d681SAndroid Build Coastguard Worker %z = fmul <4 x float> %y, <float 5.0, float 6.0, float 7.0, float 8.0> 70*9880d681SAndroid Build Coastguard Worker ret <4 x float> %z 71*9880d681SAndroid Build Coastguard Worker} 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker; Same as above, but reverse operands to make sure non-canonical form is also handled. 74*9880d681SAndroid Build Coastguard Worker; CHECK: float 5 75*9880d681SAndroid Build Coastguard Worker; CHECK: float 12 76*9880d681SAndroid Build Coastguard Worker; CHECK: float 21 77*9880d681SAndroid Build Coastguard Worker; CHECK: float 32 78*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat_non_canonical: 79*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 80*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulps 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 82*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat_non_canonical(<4 x float> %x) #0 { 83*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, %x 84*9880d681SAndroid Build Coastguard Worker %z = fmul <4 x float> <float 5.0, float 6.0, float 7.0, float 8.0>, %y 85*9880d681SAndroid Build Coastguard Worker ret <4 x float> %z 86*9880d681SAndroid Build Coastguard Worker} 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker; More than one use of a constant multiply should not inhibit the optimization. 89*9880d681SAndroid Build Coastguard Worker; Instead of a chain of 2 dependent mults, this test will have 2 independent mults. 90*9880d681SAndroid Build Coastguard Worker; CHECK: float 6 91*9880d681SAndroid Build Coastguard Worker; CHECK: float 14 92*9880d681SAndroid Build Coastguard Worker; CHECK: float 24 93*9880d681SAndroid Build Coastguard Worker; CHECK: float 36 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_v4f32_two_consts_no_splat_multiple_use: 95*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 96*9880d681SAndroid Build Coastguard Worker; CHECK: ret 97*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_v4f32_two_consts_no_splat_multiple_use(<4 x float> %x) #0 { 98*9880d681SAndroid Build Coastguard Worker %y = fmul <4 x float> %x, <float 1.0, float 2.0, float 3.0, float 4.0> 99*9880d681SAndroid Build Coastguard Worker %z = fmul <4 x float> %y, <float 5.0, float 6.0, float 7.0, float 8.0> 100*9880d681SAndroid Build Coastguard Worker %a = fadd <4 x float> %y, %z 101*9880d681SAndroid Build Coastguard Worker ret <4 x float> %a 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; PR22698 - http://llvm.org/bugs/show_bug.cgi?id=22698 105*9880d681SAndroid Build Coastguard Worker; Make sure that we don't infinite loop swapping constants back and forth. 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @PR22698_splats(<4 x float> %a) #0 { 108*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast <4 x float> <float 2.0, float 2.0, float 2.0, float 2.0>, <float 3.0, float 3.0, float 3.0, float 3.0> 109*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast <4 x float> <float 4.0, float 4.0, float 4.0, float 4.0>, %mul1 110*9880d681SAndroid Build Coastguard Worker %mul3 = fmul fast <4 x float> %a, %mul2 111*9880d681SAndroid Build Coastguard Worker ret <4 x float> %mul3 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker; CHECK: float 24 114*9880d681SAndroid Build Coastguard Worker; CHECK: float 24 115*9880d681SAndroid Build Coastguard Worker; CHECK: float 24 116*9880d681SAndroid Build Coastguard Worker; CHECK: float 24 117*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22698_splats: 118*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 119*9880d681SAndroid Build Coastguard Worker; CHECK: ret 120*9880d681SAndroid Build Coastguard Worker} 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker; Same as above, but verify that non-splat vectors are handled correctly too. 123*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @PR22698_no_splats(<4 x float> %a) #0 { 124*9880d681SAndroid Build Coastguard Worker %mul1 = fmul fast <4 x float> <float 1.0, float 2.0, float 3.0, float 4.0>, <float 5.0, float 6.0, float 7.0, float 8.0> 125*9880d681SAndroid Build Coastguard Worker %mul2 = fmul fast <4 x float> <float 9.0, float 10.0, float 11.0, float 12.0>, %mul1 126*9880d681SAndroid Build Coastguard Worker %mul3 = fmul fast <4 x float> %a, %mul2 127*9880d681SAndroid Build Coastguard Worker ret <4 x float> %mul3 128*9880d681SAndroid Build Coastguard Worker 129*9880d681SAndroid Build Coastguard Worker; CHECK: float 45 130*9880d681SAndroid Build Coastguard Worker; CHECK: float 120 131*9880d681SAndroid Build Coastguard Worker; CHECK: float 231 132*9880d681SAndroid Build Coastguard Worker; CHECK: float 384 133*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: PR22698_no_splats: 134*9880d681SAndroid Build Coastguard Worker; CHECK: mulps 135*9880d681SAndroid Build Coastguard Worker; CHECK: ret 136*9880d681SAndroid Build Coastguard Worker} 137*9880d681SAndroid Build Coastguard Worker 138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c2_c4_f32: 139*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addss 140*9880d681SAndroid Build Coastguard Worker; CHECK: mulss 141*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulss 142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret 143*9880d681SAndroid Build Coastguard Workerdefine float @fmul_c2_c4_f32(float %x) #0 { 144*9880d681SAndroid Build Coastguard Worker %y = fmul float %x, 2.0 145*9880d681SAndroid Build Coastguard Worker %z = fmul float %y, 4.0 146*9880d681SAndroid Build Coastguard Worker ret float %z 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_c3_c4_f32: 150*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: addss 151*9880d681SAndroid Build Coastguard Worker; CHECK: mulss 152*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mulss 153*9880d681SAndroid Build Coastguard Worker; CHECK-NET: ret 154*9880d681SAndroid Build Coastguard Workerdefine float @fmul_c3_c4_f32(float %x) #0 { 155*9880d681SAndroid Build Coastguard Worker %y = fmul float %x, 3.0 156*9880d681SAndroid Build Coastguard Worker %z = fmul float %y, 4.0 157*9880d681SAndroid Build Coastguard Worker ret float %z 158*9880d681SAndroid Build Coastguard Worker} 159*9880d681SAndroid Build Coastguard Worker 160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_fneg_fneg_f32: 161*9880d681SAndroid Build Coastguard Worker; CHECK: mulss %xmm1, %xmm0 162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 163*9880d681SAndroid Build Coastguard Workerdefine float @fmul_fneg_fneg_f32(float %x, float %y) { 164*9880d681SAndroid Build Coastguard Worker %x.neg = fsub float -0.0, %x 165*9880d681SAndroid Build Coastguard Worker %y.neg = fsub float -0.0, %y 166*9880d681SAndroid Build Coastguard Worker %mul = fmul float %x.neg, %y.neg 167*9880d681SAndroid Build Coastguard Worker ret float %mul 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: fmul_fneg_fneg_v4f32: 170*9880d681SAndroid Build Coastguard Worker; CHECK: mulps {{%xmm1|\(%rdx\)}}, %xmm0 171*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 172*9880d681SAndroid Build Coastguard Workerdefine <4 x float> @fmul_fneg_fneg_v4f32(<4 x float> %x, <4 x float> %y) { 173*9880d681SAndroid Build Coastguard Worker %x.neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %x 174*9880d681SAndroid Build Coastguard Worker %y.neg = fsub <4 x float> <float -0.0, float -0.0, float -0.0, float -0.0>, %y 175*9880d681SAndroid Build Coastguard Worker %mul = fmul <4 x float> %x.neg, %y.neg 176*9880d681SAndroid Build Coastguard Worker ret <4 x float> %mul 177*9880d681SAndroid Build Coastguard Worker} 178*9880d681SAndroid Build Coastguard Worker 179*9880d681SAndroid Build Coastguard Workerattributes #0 = { "less-precise-fpmad"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "unsafe-fp-math"="true" } 180