| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | |
| ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu \ | |
| ; RUN: < %s | FileCheck -check-prefix=CHECK-FAST %s | |
| ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu \ | |
| ; RUN: -mattr=-vsx < %s | FileCheck -check-prefix=CHECK-FAST-NOVSX %s | |
| ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s | |
| define dso_local double @fma_combine1(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine1: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine1: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 3, 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine1: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %fneg1, %b | |
| %add = fsub nsz contract double %mul, %a | |
| ret double %add | |
| } | |
| define double @fma_combine1_safe(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine1_safe: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 3 | |
| ; CHECK-FAST-NEXT: xsmsubadp 1, 0, 2 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine1_safe: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: fmsub 1, 0, 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine1_safe: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnegdp 0, 3 | |
| ; CHECK-NEXT: xsmsubadp 1, 0, 2 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %fneg1, %b | |
| %add = fsub contract double %mul, %a | |
| ret double %add | |
| } | |
| define dso_local double @fma_combine2(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine2: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnmaddadp 1, 2, 3 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine2: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 2, 3, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine2: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnmaddadp 1, 2, 3 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %b, %fneg1 | |
| %add = fsub nsz contract double %mul, %a | |
| ret double %add | |
| } | |
| define double @fma_combine2_safe(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine2_safe: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 3 | |
| ; CHECK-FAST-NEXT: xsmsubadp 1, 2, 0 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine2_safe: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: fmsub 1, 2, 0, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine2_safe: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnegdp 0, 3 | |
| ; CHECK-NEXT: xsmsubadp 1, 2, 0 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %b, %fneg1 | |
| %add = fsub contract double %mul, %a | |
| ret double %add | |
| } | |
| @v = common dso_local local_unnamed_addr global double 0.000000e+00, align 8 | |
| @z = common dso_local local_unnamed_addr global double 0.000000e+00, align 8 | |
| define dso_local double @fma_combine_two_uses(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine_two_uses: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 1 | |
| ; CHECK-FAST-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-FAST-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 3 | |
| ; CHECK-FAST-NEXT: addis 3, 2, z@toc@ha | |
| ; CHECK-FAST-NEXT: stfd 0, z@toc@l(3) | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_two_uses: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 3, 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, z@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: stfd 0, z@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_two_uses: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnegdp 0, 1 | |
| ; CHECK-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-NEXT: xsnegdp 0, 3 | |
| ; CHECK-NEXT: addis 3, 2, z@toc@ha | |
| ; CHECK-NEXT: stfd 0, z@toc@l(3) | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg = fneg double %a | |
| store double %fneg, ptr @v, align 8 | |
| %fneg1 = fneg double %c | |
| store double %fneg1, ptr @z, align 8 | |
| %mul = fmul contract double %fneg1, %b | |
| %add = fsub nsz contract double %mul, %a | |
| ret double %add | |
| } | |
| define dso_local double @fma_combine_one_use(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine_one_use: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 1 | |
| ; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-FAST-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_one_use: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 3, 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_one_use: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnegdp 0, 1 | |
| ; CHECK-NEXT: xsnmaddadp 1, 3, 2 | |
| ; CHECK-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg = fneg double %a | |
| store double %fneg, ptr @v, align 8 | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %fneg1, %b | |
| %add = fsub nsz contract double %mul, %a | |
| ret double %add | |
| } | |
| define double @fma_combine_one_use_safe(double %a, double %b, double %c) { | |
| ; CHECK-FAST-LABEL: fma_combine_one_use_safe: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 1 | |
| ; CHECK-FAST-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NEXT: xsnegdp 0, 3 | |
| ; CHECK-FAST-NEXT: xsmsubadp 1, 0, 2 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_one_use_safe: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fneg 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: fmsub 1, 0, 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_one_use_safe: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xsnegdp 0, 1 | |
| ; CHECK-NEXT: addis 3, 2, v@toc@ha | |
| ; CHECK-NEXT: stfd 0, v@toc@l(3) | |
| ; CHECK-NEXT: xsnegdp 0, 3 | |
| ; CHECK-NEXT: xsmsubadp 1, 0, 2 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %fneg = fneg double %a | |
| store double %fneg, ptr @v, align 8 | |
| %fneg1 = fneg double %c | |
| %mul = fmul contract double %fneg1, %b | |
| %add = fsub contract double %mul, %a | |
| ret double %add | |
| } | |
| define dso_local float @fma_combine_no_ice(ptr %ptmp, ptr %ptmp2, ptr %ptmp6, ptr %ptmp7) { | |
| ; CHECK-FAST-LABEL: fma_combine_no_ice: | |
| ; CHECK-FAST: # %bb.0: | |
| ; CHECK-FAST-NEXT: vspltisw 2, 1 | |
| ; CHECK-FAST-NEXT: lfs 0, 0(3) | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI7_0@toc@ha | |
| ; CHECK-FAST-NEXT: lfs 5, 0(6) | |
| ; CHECK-FAST-NEXT: lfs 2, 0(4) | |
| ; CHECK-FAST-NEXT: xvcvsxwdp 3, 34 | |
| ; CHECK-FAST-NEXT: lfs 1, .LCPI7_0@toc@l(3) | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI7_1@toc@ha | |
| ; CHECK-FAST-NEXT: fmr 4, 3 | |
| ; CHECK-FAST-NEXT: xsmaddasp 3, 5, 1 | |
| ; CHECK-FAST-NEXT: xsmaddasp 4, 0, 1 | |
| ; CHECK-FAST-NEXT: lfs 1, .LCPI7_1@toc@l(3) | |
| ; CHECK-FAST-NEXT: lfs 0, 0(5) | |
| ; CHECK-FAST-NEXT: xsmaddasp 1, 2, 4 | |
| ; CHECK-FAST-NEXT: xsnmsubasp 1, 3, 0 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_no_ice: | |
| ; CHECK-FAST-NOVSX: # %bb.0: | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 0, 0(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI7_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 5, 0(6) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 1, 0(4) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 4, 0(5) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 2, .LCPI7_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI7_1@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI7_1@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI7_2@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 0, 0, 3, 2 | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 2, 5, 3, 2 | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI7_2@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 0, 1, 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: fnmsubs 1, 2, 4, 0 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_no_ice: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: vspltisw 2, 1 | |
| ; CHECK-NEXT: lfs 0, 0(3) | |
| ; CHECK-NEXT: addis 3, 2, .LCPI7_0@toc@ha | |
| ; CHECK-NEXT: lfs 5, 0(6) | |
| ; CHECK-NEXT: lfs 2, 0(4) | |
| ; CHECK-NEXT: xvcvsxwdp 3, 34 | |
| ; CHECK-NEXT: lfs 1, .LCPI7_0@toc@l(3) | |
| ; CHECK-NEXT: addis 3, 2, .LCPI7_1@toc@ha | |
| ; CHECK-NEXT: fmr 4, 3 | |
| ; CHECK-NEXT: xsmaddasp 3, 5, 1 | |
| ; CHECK-NEXT: xsmaddasp 4, 0, 1 | |
| ; CHECK-NEXT: lfs 1, .LCPI7_1@toc@l(3) | |
| ; CHECK-NEXT: lfs 0, 0(5) | |
| ; CHECK-NEXT: xsmaddasp 1, 2, 4 | |
| ; CHECK-NEXT: xsnmsubasp 1, 3, 0 | |
| ; CHECK-NEXT: blr | |
| %tmp = load float, ptr %ptmp, align 4 | |
| %tmp2 = load float, ptr %ptmp2, align 4 | |
| %tmp3 = fmul contract reassoc float %tmp, 0x3FE372D780000000 | |
| %tmp4 = fadd nsz contract reassoc float %tmp3, 1.000000e+00 | |
| %tmp5 = fmul contract reassoc float %tmp2, %tmp4 | |
| %tmp6 = load float, ptr %ptmp6, align 4 | |
| %tmp7 = load float, ptr %ptmp7, align 4 | |
| %tmp8 = fmul contract reassoc float %tmp7, 0x3FE372D780000000 | |
| %tmp9 = fsub contract reassoc nsz float -1.000000e+00, %tmp8 | |
| %tmp10 = fmul contract reassoc float %tmp9, %tmp6 | |
| %tmp11 = fadd nsz contract reassoc float %tmp5, 5.000000e-01 | |
| %tmp12 = fadd nsz contract reassoc float %tmp11, %tmp10 | |
| ret float %tmp12 | |
| } | |
| define float @fma_combine_no_ice_safe(ptr %ptmp, ptr %ptmp2, ptr %ptmp6, ptr %ptmp7) { | |
| ; CHECK-FAST-LABEL: fma_combine_no_ice_safe: | |
| ; CHECK-FAST: # %bb.0: | |
| ; CHECK-FAST-NEXT: vspltisw 2, 1 | |
| ; CHECK-FAST-NEXT: lfs 0, 0(3) | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI8_0@toc@ha | |
| ; CHECK-FAST-NEXT: lfs 5, 0(6) | |
| ; CHECK-FAST-NEXT: lfs 2, 0(4) | |
| ; CHECK-FAST-NEXT: xvcvsxwdp 3, 34 | |
| ; CHECK-FAST-NEXT: lfs 1, .LCPI8_0@toc@l(3) | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI8_1@toc@ha | |
| ; CHECK-FAST-NEXT: fmr 4, 3 | |
| ; CHECK-FAST-NEXT: xsnmaddasp 3, 5, 1 | |
| ; CHECK-FAST-NEXT: xsmaddasp 4, 0, 1 | |
| ; CHECK-FAST-NEXT: lfs 1, .LCPI8_1@toc@l(3) | |
| ; CHECK-FAST-NEXT: lfs 0, 0(5) | |
| ; CHECK-FAST-NEXT: xsmaddasp 1, 2, 4 | |
| ; CHECK-FAST-NEXT: xsmaddasp 1, 3, 0 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_no_ice_safe: | |
| ; CHECK-FAST-NOVSX: # %bb.0: | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 0, 0(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI8_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 5, 0(6) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 1, 0(4) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 4, 0(5) | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 2, .LCPI8_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI8_1@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI8_1@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI8_2@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 0, 0, 3, 2 | |
| ; CHECK-FAST-NOVSX-NEXT: fnmadds 2, 5, 3, 2 | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI8_2@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 0, 1, 0, 3 | |
| ; CHECK-FAST-NOVSX-NEXT: fmadds 1, 2, 4, 0 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_no_ice_safe: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: vspltisw 2, 1 | |
| ; CHECK-NEXT: lfs 0, 0(3) | |
| ; CHECK-NEXT: addis 3, 2, .LCPI8_0@toc@ha | |
| ; CHECK-NEXT: lfs 5, 0(6) | |
| ; CHECK-NEXT: lfs 2, 0(4) | |
| ; CHECK-NEXT: xvcvsxwdp 3, 34 | |
| ; CHECK-NEXT: lfs 1, .LCPI8_0@toc@l(3) | |
| ; CHECK-NEXT: addis 3, 2, .LCPI8_1@toc@ha | |
| ; CHECK-NEXT: fmr 4, 3 | |
| ; CHECK-NEXT: xsnmaddasp 3, 5, 1 | |
| ; CHECK-NEXT: xsmaddasp 4, 0, 1 | |
| ; CHECK-NEXT: lfs 1, .LCPI8_1@toc@l(3) | |
| ; CHECK-NEXT: lfs 0, 0(5) | |
| ; CHECK-NEXT: xsmaddasp 1, 2, 4 | |
| ; CHECK-NEXT: xsmaddasp 1, 3, 0 | |
| ; CHECK-NEXT: blr | |
| %tmp = load float, ptr %ptmp, align 4 | |
| %tmp2 = load float, ptr %ptmp2, align 4 | |
| %tmp3 = fmul contract reassoc float %tmp, 0x3FE372D780000000 | |
| %tmp4 = fadd contract reassoc float %tmp3, 1.000000e+00 | |
| %tmp5 = fmul contract reassoc float %tmp2, %tmp4 | |
| %tmp6 = load float, ptr %ptmp6, align 4 | |
| %tmp7 = load float, ptr %ptmp7, align 4 | |
| %tmp8 = fmul contract reassoc float %tmp7, 0x3FE372D780000000 | |
| %tmp9 = fsub contract reassoc nsz float -1.000000e+00, %tmp8 | |
| %tmp10 = fmul contract reassoc float %tmp9, %tmp6 | |
| %tmp11 = fadd contract reassoc float %tmp5, 5.000000e-01 | |
| %tmp12 = fadd contract reassoc float %tmp11, %tmp10 | |
| ret float %tmp12 | |
| } | |
| ; This would crash while trying getNegatedExpression(). | |
| define dso_local double @getNegatedExpression_crash(double %x, double %y) { | |
| ; CHECK-FAST-LABEL: getNegatedExpression_crash: | |
| ; CHECK-FAST: # %bb.0: | |
| ; CHECK-FAST-NEXT: vspltisw 2, -1 | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI9_0@toc@ha | |
| ; CHECK-FAST-NEXT: xvcvsxwdp 4, 34 | |
| ; CHECK-FAST-NEXT: lfs 3, .LCPI9_0@toc@l(3) | |
| ; CHECK-FAST-NEXT: xssubdp 0, 1, 4 | |
| ; CHECK-FAST-NEXT: xsmaddadp 4, 1, 3 | |
| ; CHECK-FAST-NEXT: xsmaddadp 0, 4, 2 | |
| ; CHECK-FAST-NEXT: fmr 1, 0 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: getNegatedExpression_crash: | |
| ; CHECK-FAST-NOVSX: # %bb.0: | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI9_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 0, .LCPI9_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI9_1@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI9_1@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fmadd 3, 1, 3, 0 | |
| ; CHECK-FAST-NOVSX-NEXT: fsub 0, 1, 0 | |
| ; CHECK-FAST-NOVSX-NEXT: fmadd 1, 3, 2, 0 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: getNegatedExpression_crash: | |
| ; CHECK: # %bb.0: | |
| ; CHECK-NEXT: vspltisw 2, -1 | |
| ; CHECK-NEXT: addis 3, 2, .LCPI9_0@toc@ha | |
| ; CHECK-NEXT: xvcvsxwdp 4, 34 | |
| ; CHECK-NEXT: lfs 3, .LCPI9_0@toc@l(3) | |
| ; CHECK-NEXT: xssubdp 0, 1, 4 | |
| ; CHECK-NEXT: xsmaddadp 4, 1, 3 | |
| ; CHECK-NEXT: xsmaddadp 0, 4, 2 | |
| ; CHECK-NEXT: fmr 1, 0 | |
| ; CHECK-NEXT: blr | |
| %neg = fneg reassoc double %x | |
| %fma = call reassoc nsz double @llvm.fma.f64(double %neg, double 42.0, double -1.0) | |
| %add = fadd reassoc nsz double %x, 1.0 | |
| %fma1 = call reassoc nsz double @llvm.fma.f64(double %fma, double %y, double %add) | |
| ret double %fma1 | |
| } | |
| define dso_local double @fma_flag_propagation(double %a) { | |
| ; CHECK-FAST-LABEL: fma_flag_propagation: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xxlxor 1, 1, 1 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI10_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI10_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_flag_propagation: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xxlxor 1, 1, 1 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %0 = fneg double %a | |
| %1 = call reassoc nnan double @llvm.fma.f64(double %0, double 1.0, double %a) | |
| ret double %1 | |
| } | |
| define dso_local double @neg_fma_flag_propagation(double %a) { | |
| ; CHECK-FAST-LABEL: neg_fma_flag_propagation: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xxlxor 1, 1, 1 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: neg_fma_flag_propagation: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI11_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI11_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: neg_fma_flag_propagation: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xxlxor 1, 1, 1 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a) | |
| ret double %0 | |
| } | |
| define <2 x double> @vec_neg_fma_flag_propagation(<2 x double> %a) { | |
| ; CHECK-FAST-LABEL: vec_neg_fma_flag_propagation: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: xxleqv 0, 0, 0 | |
| ; CHECK-FAST-NEXT: xvcvsxwdp 0, 0 | |
| ; CHECK-FAST-NEXT: xvmaddadp 34, 34, 0 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: vec_neg_fma_flag_propagation: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI12_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI12_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fmr 2, 1 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: vec_neg_fma_flag_propagation: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: xxleqv 0, 0, 0 | |
| ; CHECK-NEXT: xvcvsxwdp 0, 0 | |
| ; CHECK-NEXT: xvmaddadp 34, 34, 0 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %0 = call reassoc nnan <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> <double -1.0, double -1.0>, <2 x double> %a) | |
| ret <2 x double> %0 | |
| } | |
| define dso_local double @fma_combine_const(double %a, double %b) { | |
| ; CHECK-FAST-LABEL: fma_combine_const: | |
| ; CHECK-FAST: # %bb.0: # %entry | |
| ; CHECK-FAST-NEXT: addis 3, 2, .LCPI13_0@toc@ha | |
| ; CHECK-FAST-NEXT: lfd 0, .LCPI13_0@toc@l(3) | |
| ; CHECK-FAST-NEXT: xsmaddadp 2, 1, 0 | |
| ; CHECK-FAST-NEXT: fmr 1, 2 | |
| ; CHECK-FAST-NEXT: blr | |
| ; | |
| ; CHECK-FAST-NOVSX-LABEL: fma_combine_const: | |
| ; CHECK-FAST-NOVSX: # %bb.0: # %entry | |
| ; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI13_0@toc@ha | |
| ; CHECK-FAST-NOVSX-NEXT: lfd 0, .LCPI13_0@toc@l(3) | |
| ; CHECK-FAST-NOVSX-NEXT: fmadd 1, 1, 0, 2 | |
| ; CHECK-FAST-NOVSX-NEXT: blr | |
| ; | |
| ; CHECK-LABEL: fma_combine_const: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: addis 3, 2, .LCPI13_0@toc@ha | |
| ; CHECK-NEXT: lfd 0, .LCPI13_0@toc@l(3) | |
| ; CHECK-NEXT: xsmaddadp 2, 1, 0 | |
| ; CHECK-NEXT: fmr 1, 2 | |
| ; CHECK-NEXT: blr | |
| entry: | |
| %0 = fmul reassoc double %a, 1.1 | |
| %1 = call contract reassoc double @llvm.fma.f64(double %0, double 2.1, double %b) | |
| ret double %1 | |
| } | |
| declare double @llvm.fma.f64(double, double, double) nounwind readnone | |
| declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone |