-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LoongArch] Add codegen support for [X]VF{MSUB/NMADD/NMSUB}.{S/D} ins… #74819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-backend-loongarch Author: wanglei (wangleiat) Changes…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:
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]
|
…tructions This is similar to single and double-precision floating-point instructions.
SixWeining
approved these changes
Dec 8, 2023
leecheechen
pushed a commit
to leecheechen/llvm-project
that referenced
this pull request
Jun 9, 2025
…tructions (llvm#74819) This is similar to single and double-precision floating-point instructions. (cherry picked from commit af999c4) Change-Id: I4b946a4a4e6e0869aec43e6b085025a06a11e012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
…tructions
This is similar to single and double-precision floating-point instructions.