Esme-Yi 29eb3dcfe6 [PowerPC] Materialize i64 constants by enumerated patterns.
Summary: Some constants can be handled with less instructions than our current results. And it seems our original approach is not very easy to extend. Therefore this patch proposes to materialize all 64-bit constants by enumerated patterns.
I traversed almost all constants to verified the functionality of these pattens. A traversed comparison of the number of instructions used by the original method and the new method has also been completed, where no degradation was caused by this patch. This patch also passed Bootstrap test and SPEC test.
Improvements of this patch are shown in llvm/test/CodeGen/PowerPC/constants-i64.ll

Reviewed By: steven.zhang, stefanp

Differential Revision: https://reviews.llvm.org/D92089
2020-12-21 05:21:07 +00:00

560 lines
19 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unknown-unknown \
; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s
; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown \
; RUN: -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names < %s | FileCheck %s \
; RUN: -check-prefix=CHECK-P8
define void @qpFmadd(fp128* nocapture readonly %a, fp128* nocapture %b,
; CHECK-LABEL: qpFmadd:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsmaddqp v4, v2, v3
; CHECK-NEXT: stxv v4, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFmadd:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r28, -32
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r28, -32(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r7, 0(r3)
; CHECK-P8-NEXT: ld r8, 8(r3)
; CHECK-P8-NEXT: ld r9, 0(r4)
; CHECK-P8-NEXT: ld r10, 8(r4)
; CHECK-P8-NEXT: mr r28, r6
; CHECK-P8-NEXT: ld r30, 0(r5)
; CHECK-P8-NEXT: ld r29, 8(r5)
; CHECK-P8-NEXT: mr r3, r7
; CHECK-P8-NEXT: mr r4, r8
; CHECK-P8-NEXT: mr r5, r9
; CHECK-P8-NEXT: mr r6, r10
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: mr r5, r30
; CHECK-P8-NEXT: mr r6, r29
; CHECK-P8-NEXT: bl __addkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: std r3, 0(r28)
; CHECK-P8-NEXT: std r4, 8(r28)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r28, -32(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%madd = tail call fp128 @llvm.fmuladd.f128(fp128 %0, fp128 %1, fp128 %2)
store fp128 %madd, fp128* %res, align 16
ret void
}
declare fp128 @llvm.fmuladd.f128(fp128, fp128, fp128)
; Function Attrs: norecurse nounwind
define void @qpFmadd_02(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFmadd_02:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsmaddqp v2, v3, v4
; CHECK-NEXT: stxv v2, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFmadd_02:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r28, -32
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r28, -32(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r7, 0(r5)
; CHECK-P8-NEXT: ld r8, 8(r5)
; CHECK-P8-NEXT: ld r30, 0(r3)
; CHECK-P8-NEXT: ld r29, 8(r3)
; CHECK-P8-NEXT: mr r28, r6
; CHECK-P8-NEXT: ld r3, 0(r4)
; CHECK-P8-NEXT: ld r4, 8(r4)
; CHECK-P8-NEXT: mr r5, r7
; CHECK-P8-NEXT: mr r6, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: mr r5, r3
; CHECK-P8-NEXT: mr r6, r4
; CHECK-P8-NEXT: mr r3, r30
; CHECK-P8-NEXT: mr r4, r29
; CHECK-P8-NEXT: bl __addkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: std r3, 0(r28)
; CHECK-P8-NEXT: std r4, 8(r28)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r28, -32(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%mul = fmul contract fp128 %1, %2
%add = fadd contract fp128 %0, %mul
store fp128 %add, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFmadd_03(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFmadd_03:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsmaddqp v4, v2, v3
; CHECK-NEXT: stxv v4, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFmadd_03:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r9, 0(r3)
; CHECK-P8-NEXT: ld r7, 8(r3)
; CHECK-P8-NEXT: ld r8, 0(r4)
; CHECK-P8-NEXT: mr r30, r6
; CHECK-P8-NEXT: ld r6, 8(r4)
; CHECK-P8-NEXT: mr r29, r5
; CHECK-P8-NEXT: mr r3, r9
; CHECK-P8-NEXT: mr r4, r7
; CHECK-P8-NEXT: mr r5, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: ld r5, 0(r29)
; CHECK-P8-NEXT: ld r6, 8(r29)
; CHECK-P8-NEXT: bl __addkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: std r3, 0(r30)
; CHECK-P8-NEXT: std r4, 8(r30)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%mul = fmul contract fp128 %0, %1
%2 = load fp128, fp128* %c, align 16
%add = fadd contract fp128 %mul, %2
store fp128 %add, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFnmadd(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFnmadd:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsnmaddqp v2, v3, v4
; CHECK-NEXT: stxv v2, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFnmadd:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r28, -32
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r28, -32(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r7, 0(r5)
; CHECK-P8-NEXT: ld r8, 8(r5)
; CHECK-P8-NEXT: ld r30, 0(r3)
; CHECK-P8-NEXT: ld r29, 8(r3)
; CHECK-P8-NEXT: mr r28, r6
; CHECK-P8-NEXT: ld r3, 0(r4)
; CHECK-P8-NEXT: ld r4, 8(r4)
; CHECK-P8-NEXT: mr r5, r7
; CHECK-P8-NEXT: mr r6, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: mr r5, r3
; CHECK-P8-NEXT: mr r6, r4
; CHECK-P8-NEXT: mr r3, r30
; CHECK-P8-NEXT: mr r4, r29
; CHECK-P8-NEXT: bl __addkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: li r5, 1
; CHECK-P8-NEXT: std r3, 0(r28)
; CHECK-P8-NEXT: rldic r5, r5, 63, 0
; CHECK-P8-NEXT: xor r4, r4, r5
; CHECK-P8-NEXT: std r4, 8(r28)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r28, -32(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%mul = fmul contract fp128 %1, %2
%add = fadd contract fp128 %0, %mul
%sub = fsub fp128 0xL00000000000000008000000000000000, %add
store fp128 %sub, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFnmadd_02(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFnmadd_02:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsnmaddqp v4, v2, v3
; CHECK-NEXT: stxv v4, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFnmadd_02:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r9, 0(r3)
; CHECK-P8-NEXT: ld r7, 8(r3)
; CHECK-P8-NEXT: ld r8, 0(r4)
; CHECK-P8-NEXT: mr r30, r6
; CHECK-P8-NEXT: ld r6, 8(r4)
; CHECK-P8-NEXT: mr r29, r5
; CHECK-P8-NEXT: mr r3, r9
; CHECK-P8-NEXT: mr r4, r7
; CHECK-P8-NEXT: mr r5, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: ld r5, 0(r29)
; CHECK-P8-NEXT: ld r6, 8(r29)
; CHECK-P8-NEXT: bl __addkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: li r5, 1
; CHECK-P8-NEXT: std r3, 0(r30)
; CHECK-P8-NEXT: rldic r5, r5, 63, 0
; CHECK-P8-NEXT: xor r4, r4, r5
; CHECK-P8-NEXT: std r4, 8(r30)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%mul = fmul contract fp128 %0, %1
%2 = load fp128, fp128* %c, align 16
%add = fadd contract fp128 %mul, %2
%sub = fsub fp128 0xL00000000000000008000000000000000, %add
store fp128 %sub, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFmsub(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFmsub:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsnmsubqp v2, v3, v4
; CHECK-NEXT: stxv v2, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFmsub:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r28, -32
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r28, -32(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r7, 0(r5)
; CHECK-P8-NEXT: ld r8, 8(r5)
; CHECK-P8-NEXT: ld r30, 0(r3)
; CHECK-P8-NEXT: ld r29, 8(r3)
; CHECK-P8-NEXT: mr r28, r6
; CHECK-P8-NEXT: ld r3, 0(r4)
; CHECK-P8-NEXT: ld r4, 8(r4)
; CHECK-P8-NEXT: mr r5, r7
; CHECK-P8-NEXT: mr r6, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: mr r5, r3
; CHECK-P8-NEXT: mr r6, r4
; CHECK-P8-NEXT: mr r3, r30
; CHECK-P8-NEXT: mr r4, r29
; CHECK-P8-NEXT: bl __subkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: std r3, 0(r28)
; CHECK-P8-NEXT: std r4, 8(r28)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r28, -32(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%mul = fmul contract fp128 %1, %2
%sub = fsub contract nsz fp128 %0, %mul
store fp128 %sub, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFmsub_02(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFmsub_02:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsmsubqp v4, v2, v3
; CHECK-NEXT: stxv v4, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFmsub_02:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r9, 0(r3)
; CHECK-P8-NEXT: ld r7, 8(r3)
; CHECK-P8-NEXT: ld r8, 0(r4)
; CHECK-P8-NEXT: mr r30, r6
; CHECK-P8-NEXT: ld r6, 8(r4)
; CHECK-P8-NEXT: mr r29, r5
; CHECK-P8-NEXT: mr r3, r9
; CHECK-P8-NEXT: mr r4, r7
; CHECK-P8-NEXT: mr r5, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: ld r5, 0(r29)
; CHECK-P8-NEXT: ld r6, 8(r29)
; CHECK-P8-NEXT: bl __subkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: std r3, 0(r30)
; CHECK-P8-NEXT: std r4, 8(r30)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%mul = fmul contract fp128 %0, %1
%2 = load fp128, fp128* %c, align 16
%sub = fsub contract fp128 %mul, %2
store fp128 %sub, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFnmsub(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFnmsub:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsnegqp v3, v3
; CHECK-NEXT: xsnmaddqp v2, v3, v4
; CHECK-NEXT: stxv v2, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFnmsub:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r28, -32
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r28, -32(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r7, 0(r5)
; CHECK-P8-NEXT: ld r8, 8(r5)
; CHECK-P8-NEXT: ld r30, 0(r3)
; CHECK-P8-NEXT: ld r29, 8(r3)
; CHECK-P8-NEXT: mr r28, r6
; CHECK-P8-NEXT: ld r3, 0(r4)
; CHECK-P8-NEXT: ld r4, 8(r4)
; CHECK-P8-NEXT: mr r5, r7
; CHECK-P8-NEXT: mr r6, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: mr r5, r3
; CHECK-P8-NEXT: mr r6, r4
; CHECK-P8-NEXT: mr r3, r30
; CHECK-P8-NEXT: mr r4, r29
; CHECK-P8-NEXT: bl __subkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: li r5, 1
; CHECK-P8-NEXT: std r3, 0(r28)
; CHECK-P8-NEXT: rldic r5, r5, 63, 0
; CHECK-P8-NEXT: xor r4, r4, r5
; CHECK-P8-NEXT: std r4, 8(r28)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r28, -32(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%2 = load fp128, fp128* %c, align 16
%mul = fmul contract fp128 %1, %2
%sub = fsub contract fp128 %0, %mul
%sub1 = fsub fp128 0xL00000000000000008000000000000000, %sub
store fp128 %sub1, fp128* %res, align 16
ret void
}
; Function Attrs: norecurse nounwind
define void @qpFnmsub_02(fp128* nocapture readonly %a,
; CHECK-LABEL: qpFnmsub_02:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: lxv v2, 0(r3)
; CHECK-NEXT: lxv v3, 0(r4)
; CHECK-NEXT: lxv v4, 0(r5)
; CHECK-NEXT: xsnmsubqp v4, v2, v3
; CHECK-NEXT: stxv v4, 0(r6)
; CHECK-NEXT: blr
;
; CHECK-P8-LABEL: qpFnmsub_02:
; CHECK-P8: # %bb.0: # %entry
; CHECK-P8-NEXT: mflr r0
; CHECK-P8-NEXT: .cfi_def_cfa_offset 64
; CHECK-P8-NEXT: .cfi_offset lr, 16
; CHECK-P8-NEXT: .cfi_offset r29, -24
; CHECK-P8-NEXT: .cfi_offset r30, -16
; CHECK-P8-NEXT: std r29, -24(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r30, -16(r1) # 8-byte Folded Spill
; CHECK-P8-NEXT: std r0, 16(r1)
; CHECK-P8-NEXT: stdu r1, -64(r1)
; CHECK-P8-NEXT: ld r9, 0(r3)
; CHECK-P8-NEXT: ld r7, 8(r3)
; CHECK-P8-NEXT: ld r8, 0(r4)
; CHECK-P8-NEXT: mr r30, r6
; CHECK-P8-NEXT: ld r6, 8(r4)
; CHECK-P8-NEXT: mr r29, r5
; CHECK-P8-NEXT: mr r3, r9
; CHECK-P8-NEXT: mr r4, r7
; CHECK-P8-NEXT: mr r5, r8
; CHECK-P8-NEXT: bl __mulkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: ld r5, 0(r29)
; CHECK-P8-NEXT: ld r6, 8(r29)
; CHECK-P8-NEXT: bl __subkf3
; CHECK-P8-NEXT: nop
; CHECK-P8-NEXT: li r5, 1
; CHECK-P8-NEXT: std r3, 0(r30)
; CHECK-P8-NEXT: rldic r5, r5, 63, 0
; CHECK-P8-NEXT: xor r4, r4, r5
; CHECK-P8-NEXT: std r4, 8(r30)
; CHECK-P8-NEXT: addi r1, r1, 64
; CHECK-P8-NEXT: ld r0, 16(r1)
; CHECK-P8-NEXT: ld r30, -16(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: ld r29, -24(r1) # 8-byte Folded Reload
; CHECK-P8-NEXT: mtlr r0
; CHECK-P8-NEXT: blr
fp128* nocapture readonly %b,
fp128* nocapture readonly %c, fp128* nocapture %res) {
entry:
%0 = load fp128, fp128* %a, align 16
%1 = load fp128, fp128* %b, align 16
%mul = fmul contract fp128 %0, %1
%2 = load fp128, fp128* %c, align 16
%sub = fsub contract fp128 %mul, %2
%sub1 = fsub fp128 0xL00000000000000008000000000000000, %sub
store fp128 %sub1, fp128* %res, align 16
ret void
}