[llvm] [LoongArch] Add codegen support for [X]VF{MSUB/NMADD/NMSUB}.{S/D} ins… (PR #74819)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 8 01:13:30 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-loongarch
Author: wanglei (wangleiat)
<details>
<summary>Changes</summary>
…tructions
This is similar to single and double-precision floating-point instructions.
---
Patch is 122.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74819.diff
6 Files Affected:
- (modified) llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td (+26)
- (modified) llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td (+26)
- (added) llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll (+804)
- (added) llvm/test/CodeGen/LoongArch/lasx/fma-v8f32.ll (+804)
- (added) llvm/test/CodeGen/LoongArch/lsx/fma-v2f64.ll (+804)
- (added) llvm/test/CodeGen/LoongArch/lsx/fma-v4f32.ll (+804)
``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
index 8559baa0e525f..ec6983d0f4871 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLASXInstrInfo.td
@@ -1455,6 +1455,32 @@ def : Pat<(fma v8f32:$xj, v8f32:$xk, v8f32:$xa),
def : Pat<(fma v4f64:$xj, v4f64:$xk, v4f64:$xa),
(XVFMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+// XVFMSUB_{S/D}
+def : Pat<(fma v8f32:$xj, v8f32:$xk, (fneg v8f32:$xa)),
+ (XVFMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>;
+def : Pat<(fma v4f64:$xj, v4f64:$xk, (fneg v4f64:$xa)),
+ (XVFMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+
+// XVFNMADD_{S/D}
+def : Pat<(fneg (fma v8f32:$xj, v8f32:$xk, v8f32:$xa)),
+ (XVFNMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>;
+def : Pat<(fneg (fma v4f64:$xj, v4f64:$xk, v4f64:$xa)),
+ (XVFNMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+def : Pat<(fma_nsz (fneg v8f32:$xj), v8f32:$xk, (fneg v8f32:$xa)),
+ (XVFNMADD_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>;
+def : Pat<(fma_nsz (fneg v4f64:$xj), v4f64:$xk, (fneg v4f64:$xa)),
+ (XVFNMADD_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+
+// XVFNMSUB_{S/D}
+def : Pat<(fneg (fma v8f32:$xj, v8f32:$xk, (fneg v8f32:$xa))),
+ (XVFNMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>;
+def : Pat<(fneg (fma v4f64:$xj, v4f64:$xk, (fneg v4f64:$xa))),
+ (XVFNMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+def : Pat<(fma_nsz (fneg v8f32:$xj), v8f32:$xk, v8f32:$xa),
+ (XVFNMSUB_S v8f32:$xj, v8f32:$xk, v8f32:$xa)>;
+def : Pat<(fma_nsz (fneg v4f64:$xj), v4f64:$xk, v4f64:$xa),
+ (XVFNMSUB_D v4f64:$xj, v4f64:$xk, v4f64:$xa)>;
+
// XVFSQRT_{S/D}
defm : PatXrF<fsqrt, "XVFSQRT">;
diff --git a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
index 5947f241bb597..e468176885d75 100644
--- a/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchLSXInstrInfo.td
@@ -1555,6 +1555,32 @@ def : Pat<(fma v4f32:$vj, v4f32:$vk, v4f32:$va),
def : Pat<(fma v2f64:$vj, v2f64:$vk, v2f64:$va),
(VFMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+// VFMSUB_{S/D}
+def : Pat<(fma v4f32:$vj, v4f32:$vk, (fneg v4f32:$va)),
+ (VFMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>;
+def : Pat<(fma v2f64:$vj, v2f64:$vk, (fneg v2f64:$va)),
+ (VFMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+
+// VFNMADD_{S/D}
+def : Pat<(fneg (fma v4f32:$vj, v4f32:$vk, v4f32:$va)),
+ (VFNMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>;
+def : Pat<(fneg (fma v2f64:$vj, v2f64:$vk, v2f64:$va)),
+ (VFNMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+def : Pat<(fma_nsz (fneg v4f32:$vj), v4f32:$vk, (fneg v4f32:$va)),
+ (VFNMADD_S v4f32:$vj, v4f32:$vk, v4f32:$va)>;
+def : Pat<(fma_nsz (fneg v2f64:$vj), v2f64:$vk, (fneg v2f64:$va)),
+ (VFNMADD_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+
+// VFNMSUB_{S/D}
+def : Pat<(fneg (fma v4f32:$vj, v4f32:$vk, (fneg v4f32:$va))),
+ (VFNMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>;
+def : Pat<(fneg (fma v2f64:$vj, v2f64:$vk, (fneg v2f64:$va))),
+ (VFNMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+def : Pat<(fma_nsz (fneg v4f32:$vj), v4f32:$vk, v4f32:$va),
+ (VFNMSUB_S v4f32:$vj, v4f32:$vk, v4f32:$va)>;
+def : Pat<(fma_nsz (fneg v2f64:$vj), v2f64:$vk, v2f64:$va),
+ (VFNMSUB_D v2f64:$vj, v2f64:$vk, v2f64:$va)>;
+
// VFSQRT_{S/D}
defm : PatVrF<fsqrt, "VFSQRT">;
diff --git a/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll b/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll
new file mode 100644
index 0000000000000..39dfee6bc2206
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/lasx/fma-v4f64.ll
@@ -0,0 +1,804 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=fast < %s \
+; RUN: | FileCheck %s --check-prefix=CONTRACT-FAST
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=on < %s \
+; RUN: | FileCheck %s --check-prefix=CONTRACT-ON
+; RUN: llc --mtriple=loongarch64 --mattr=+lasx --fp-contract=off < %s \
+; RUN: | FileCheck %s --check-prefix=CONTRACT-OFF
+
+define void @fmadd_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fmadd_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fmadd_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfadd.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fmadd_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfadd.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %mul = fmul<4 x double> %v0, %v1
+ %add = fadd<4 x double> %mul, %v2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+define void @fmsub_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fmsub_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fmsub_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fmsub_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %mul = fmul<4 x double> %v0, %v1
+ %sub = fsub<4 x double> %mul, %v2
+ store <4 x double> %sub, ptr %res
+ ret void
+}
+
+define void @fnmadd_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fnmadd_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fnmadd_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfadd.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvbitrevi.d $xr0, $xr0, 63
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fnmadd_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfadd.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvbitrevi.d $xr0, $xr0, 63
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %mul = fmul<4 x double> %v0, %v1
+ %add = fadd<4 x double> %mul, %v2
+ %negadd = fneg<4 x double> %add
+ store <4 x double> %negadd, ptr %res
+ ret void
+}
+
+define void @fnmadd_v4f64_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fnmadd_v4f64_nsz:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fnmadd_v4f64_nsz:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvbitrevi.d $xr1, $xr1, 63
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fnmadd_v4f64_nsz:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvbitrevi.d $xr1, $xr1, 63
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %negv0 = fneg nsz<4 x double> %v0
+ %negv2 = fneg nsz<4 x double> %v2
+ %mul = fmul nsz<4 x double> %negv0, %v1
+ %add = fadd nsz<4 x double> %mul, %negv2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+;; Check that fnmadd.s is not emitted.
+define void @not_fnmadd_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: not_fnmadd_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63
+; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: not_fnmadd_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvbitrevi.d $xr1, $xr1, 63
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: not_fnmadd_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvbitrevi.d $xr1, $xr1, 63
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %negv0 = fneg<4 x double> %v0
+ %negv2 = fneg<4 x double> %v2
+ %mul = fmul<4 x double> %negv0, %v1
+ %add = fadd<4 x double> %mul, %negv2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+define void @fnmsub_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fnmsub_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fnmsub_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-ON-NEXT: xvbitrevi.d $xr0, $xr0, 63
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fnmsub_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr0, $xr1
+; CONTRACT-OFF-NEXT: xvbitrevi.d $xr0, $xr0, 63
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %negv2 = fneg<4 x double> %v2
+ %mul = fmul<4 x double> %v0, %v1
+ %add = fadd<4 x double> %mul, %negv2
+ %neg = fneg<4 x double> %add
+ store <4 x double> %neg, ptr %res
+ ret void
+}
+
+define void @fnmsub_v4f64_nsz(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: fnmsub_v4f64_nsz:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfnmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: fnmsub_v4f64_nsz:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: fnmsub_v4f64_nsz:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %negv0 = fneg nsz<4 x double> %v0
+ %mul = fmul nsz<4 x double> %negv0, %v1
+ %add = fadd nsz<4 x double> %mul, %v2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+;; Check that fnmsub.s is not emitted.
+define void @not_fnmsub_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: not_fnmsub_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvbitrevi.d $xr2, $xr2, 63
+; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: not_fnmsub_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-ON-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-ON-NEXT: xvfsub.d $xr0, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: not_fnmsub_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmul.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a3, 0
+; CONTRACT-OFF-NEXT: xvfsub.d $xr0, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %negv0 = fneg<4 x double> %v0
+ %mul = fmul<4 x double> %negv0, %v1
+ %add = fadd<4 x double> %mul, %v2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+define void @contract_fmadd_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: contract_fmadd_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: contract_fmadd_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-ON-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: contract_fmadd_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %mul = fmul contract <4 x double> %v0, %v1
+ %add = fadd contract <4 x double> %mul, %v2
+ store <4 x double> %add, ptr %res
+ ret void
+}
+
+define void @contract_fmsub_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: contract_fmsub_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: contract_fmsub_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-ON-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: contract_fmsub_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-OFF-NEXT: xvfmsub.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-OFF-NEXT: ret
+entry:
+ %v0 = load <4 x double>, ptr %a0
+ %v1 = load <4 x double>, ptr %a1
+ %v2 = load <4 x double>, ptr %a2
+ %mul = fmul contract <4 x double> %v0, %v1
+ %sub = fsub contract <4 x double> %mul, %v2
+ store <4 x double> %sub, ptr %res
+ ret void
+}
+
+define void @contract_fnmadd_v4f64(ptr %res, ptr %a0, ptr %a1, ptr %a2) nounwind {
+; CONTRACT-FAST-LABEL: contract_fnmadd_v4f64:
+; CONTRACT-FAST: # %bb.0: # %entry
+; CONTRACT-FAST-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-FAST-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-FAST-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-FAST-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-FAST-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-FAST-NEXT: ret
+;
+; CONTRACT-ON-LABEL: contract_fnmadd_v4f64:
+; CONTRACT-ON: # %bb.0: # %entry
+; CONTRACT-ON-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-ON-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-ON-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-ON-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-ON-NEXT: xvst $xr0, $a0, 0
+; CONTRACT-ON-NEXT: ret
+;
+; CONTRACT-OFF-LABEL: contract_fnmadd_v4f64:
+; CONTRACT-OFF: # %bb.0: # %entry
+; CONTRACT-OFF-NEXT: xvld $xr0, $a3, 0
+; CONTRACT-OFF-NEXT: xvld $xr1, $a2, 0
+; CONTRACT-OFF-NEXT: xvld $xr2, $a1, 0
+; CONTRACT-OFF-NEXT: xvfnmadd.d $xr0, $xr2, $xr1, $xr0
+; CONTRACT-OFF-NEXT: xvst $xr0, $a0, 0
+;...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/74819
More information about the llvm-commits
mailing list