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