Home | History | Annotate | Download | only in AArch64
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -verify-machineinstrs | FileCheck %s
      3 
      4 define double @test1(double %a, double %b) {
      5 ; CHECK-LABEL: test1:
      6 ; CHECK:       // %bb.0:
      7 ; CHECK-NEXT:    fadd d1, d1, d1
      8 ; CHECK-NEXT:    fsub d0, d0, d1
      9 ; CHECK-NEXT:    ret
     10   %mul = fmul double %b, -2.000000e+00
     11   %add1 = fadd double %a, %mul
     12   ret double %add1
     13 }
     14 
     15 ; DAGCombine will canonicalize 'a - 2.0*b' to 'a + -2.0*b'
     16 
     17 define double @test2(double %a, double %b) {
     18 ; CHECK-LABEL: test2:
     19 ; CHECK:       // %bb.0:
     20 ; CHECK-NEXT:    fadd d1, d1, d1
     21 ; CHECK-NEXT:    fsub d0, d0, d1
     22 ; CHECK-NEXT:    ret
     23   %mul = fmul double %b, 2.000000e+00
     24   %add1 = fsub double %a, %mul
     25   ret double %add1
     26 }
     27 
     28 define double @test3(double %a, double %b, double %c) {
     29 ; CHECK-LABEL: test3:
     30 ; CHECK:       // %bb.0:
     31 ; CHECK-NEXT:    fmul d0, d0, d1
     32 ; CHECK-NEXT:    fadd d1, d2, d2
     33 ; CHECK-NEXT:    fsub d0, d0, d1
     34 ; CHECK-NEXT:    ret
     35   %mul = fmul double %a, %b
     36   %mul1 = fmul double %c, 2.000000e+00
     37   %sub = fsub double %mul, %mul1
     38   ret double %sub
     39 }
     40 
     41 define double @test4(double %a, double %b, double %c) {
     42 ; CHECK-LABEL: test4:
     43 ; CHECK:       // %bb.0:
     44 ; CHECK-NEXT:    fmul d0, d0, d1
     45 ; CHECK-NEXT:    fadd d1, d2, d2
     46 ; CHECK-NEXT:    fsub d0, d0, d1
     47 ; CHECK-NEXT:    ret
     48   %mul = fmul double %a, %b
     49   %mul1 = fmul double %c, -2.000000e+00
     50   %add2 = fadd double %mul, %mul1
     51   ret double %add2
     52 }
     53 
     54 define <4 x float> @test5(<4 x float> %a, <4 x float> %b) {
     55 ; CHECK-LABEL: test5:
     56 ; CHECK:       // %bb.0:
     57 ; CHECK-NEXT:    fadd v1.4s, v1.4s, v1.4s
     58 ; CHECK-NEXT:    fsub v0.4s, v0.4s, v1.4s
     59 ; CHECK-NEXT:    ret
     60   %mul = fmul <4 x float> %b, <float -2.0, float -2.0, float -2.0, float -2.0>
     61   %add = fadd <4 x float> %a, %mul
     62   ret <4 x float> %add
     63 }
     64 
     65 define <4 x float> @test6(<4 x float> %a, <4 x float> %b) {
     66 ; CHECK-LABEL: test6:
     67 ; CHECK:       // %bb.0:
     68 ; CHECK-NEXT:    fadd v1.4s, v1.4s, v1.4s
     69 ; CHECK-NEXT:    fsub v0.4s, v0.4s, v1.4s
     70 ; CHECK-NEXT:    ret
     71   %mul = fmul <4 x float> %b, <float 2.0, float 2.0, float 2.0, float 2.0>
     72   %add = fsub <4 x float> %a, %mul
     73   ret <4 x float> %add
     74 }
     75 
     76 ; Don't fold (fadd A, (fmul B, -2.0)) -> (fsub A, (fadd B, B)) if the fmul has
     77 ; multiple uses.
     78 
     79 define double @test7(double %a, double %b) nounwind {
     80 ; CHECK-LABEL: test7:
     81 ; CHECK:       // %bb.0:
     82 ; CHECK-NEXT:    str d8, [sp, #-16]! // 8-byte Folded Spill
     83 ; CHECK-NEXT:    fmov d2, #-2.00000000
     84 ; CHECK-NEXT:    fmul d1, d1, d2
     85 ; CHECK-NEXT:    fadd d8, d0, d1
     86 ; CHECK-NEXT:    mov v0.16b, v1.16b
     87 ; CHECK-NEXT:    str x30, [sp, #8] // 8-byte Folded Spill
     88 ; CHECK-NEXT:    bl use
     89 ; CHECK-NEXT:    ldr x30, [sp, #8] // 8-byte Folded Reload
     90 ; CHECK-NEXT:    mov v0.16b, v8.16b
     91 ; CHECK-NEXT:    ldr d8, [sp], #16 // 8-byte Folded Reload
     92 ; CHECK-NEXT:    ret
     93   %mul = fmul double %b, -2.000000e+00
     94   %add1 = fadd double %a, %mul
     95   call void @use(double %mul)
     96   ret double %add1
     97 }
     98 
     99 define float @fadd_const_multiuse_fmf(float %x) {
    100 ; CHECK-LABEL: fadd_const_multiuse_fmf:
    101 ; CHECK:       // %bb.0:
    102 ; CHECK-NEXT:    adrp x8, .LCPI7_0
    103 ; CHECK-NEXT:    adrp x9, .LCPI7_1
    104 ; CHECK-NEXT:    ldr s1, [x8, :lo12:.LCPI7_0]
    105 ; CHECK-NEXT:    ldr s2, [x9, :lo12:.LCPI7_1]
    106 ; CHECK-NEXT:    fadd s1, s0, s1
    107 ; CHECK-NEXT:    fadd s0, s0, s2
    108 ; CHECK-NEXT:    fadd s0, s1, s0
    109 ; CHECK-NEXT:    ret
    110   %a1 = fadd float %x, 42.0
    111   %a2 = fadd nsz reassoc float %a1, 17.0
    112   %a3 = fadd float %a1, %a2
    113   ret float %a3
    114 }
    115 
    116 ; DAGCombiner transforms this into: (x + 59.0) + (x + 17.0).
    117 ; The machine combiner transforms this into a chain of 3 dependent adds:
    118 ; ((x + 59.0) + 17.0) + x
    119 
    120 define float @fadd_const_multiuse_attr(float %x) #0 {
    121 ; CHECK-LABEL: fadd_const_multiuse_attr:
    122 ; CHECK:       // %bb.0:
    123 ; CHECK-NEXT:    adrp x9, .LCPI8_1
    124 ; CHECK-NEXT:    adrp x8, .LCPI8_0
    125 ; CHECK-NEXT:    ldr s1, [x9, :lo12:.LCPI8_1]
    126 ; CHECK-NEXT:    ldr s2, [x8, :lo12:.LCPI8_0]
    127 ; CHECK-NEXT:    fadd s1, s0, s1
    128 ; CHECK-NEXT:    fadd s1, s2, s1
    129 ; CHECK-NEXT:    fadd s0, s0, s1
    130 ; CHECK-NEXT:    ret
    131   %a1 = fadd float %x, 42.0
    132   %a2 = fadd float %a1, 17.0
    133   %a3 = fadd float %a1, %a2
    134   ret float %a3
    135 }
    136 
    137 attributes #0 = { "unsafe-fp-math"="true" }
    138 
    139 declare void @use(double)
    140 
    141