[llvm] [RISCV] Implement foward inserting save/restore FRM instructions. (PR #77744)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 11:49:17 PST 2024
================
@@ -0,0 +1,217 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d < %s | FileCheck %s
+
+declare <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float>,
+ <vscale x 1 x float>,
+ <vscale x 1 x float>,
+ i64, i64)
+
+; Test only save/restore frm once.
+define <vscale x 1 x float> @test(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
+; CHECK-LABEL: test:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: fsrmi a0, 0
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: fsrm a0
+; CHECK-NEXT: ret
+entry:
+ %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %0,
+ <vscale x 1 x float> %1,
+ i64 0, i64 %2)
+ %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %a,
+ <vscale x 1 x float> %a,
+ i64 0, i64 %2)
+ ret <vscale x 1 x float> %b
+}
+
+; Test only restore frm once.
+define <vscale x 1 x float> @test2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
+; CHECK-LABEL: test2:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: fsrmi a0, 0
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: fsrmi 1
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: fsrm a0
+; CHECK-NEXT: ret
+entry:
+ %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %0,
+ <vscale x 1 x float> %1,
+ i64 0, i64 %2)
+ %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %a,
+ <vscale x 1 x float> %a,
+ i64 1, i64 %2)
+ ret <vscale x 1 x float> %b
+}
+
+; Test restoring frm before function call and doing nothing with following
+; dynamic rounding mode operations.
+declare void @foo()
+define <vscale x 1 x float> @test3(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
+; CHECK-LABEL: test3:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addi sp, sp, -32
+; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
+; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
+; CHECK-NEXT: csrr a1, vlenb
+; CHECK-NEXT: slli a1, a1, 1
+; CHECK-NEXT: sub sp, sp, a1
+; CHECK-NEXT: mv s0, a0
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: fsrmi a0, 0
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: addi a1, sp, 16
+; CHECK-NEXT: vs1r.v v8, (a1) # Unknown-size Folded Spill
+; CHECK-NEXT: fsrm a0
+; CHECK-NEXT: call foo
+; CHECK-NEXT: vsetvli zero, s0, e32, mf2, ta, ma
+; CHECK-NEXT: addi a0, sp, 16
+; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: csrr a0, vlenb
+; CHECK-NEXT: slli a0, a0, 1
+; CHECK-NEXT: add sp, sp, a0
+; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
+; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
+; CHECK-NEXT: addi sp, sp, 32
+; CHECK-NEXT: ret
+entry:
+ %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %0,
+ <vscale x 1 x float> %1,
+ i64 0, i64 %2)
+ call void @foo()
+ %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %a,
+ <vscale x 1 x float> %a,
+ i64 7, i64 %2)
+ ret <vscale x 1 x float> %b
+}
+
+; Test restoring frm before inline asm and doing nothing with following dynamic
+; rounding mode operations.
+define <vscale x 1 x float> @test4(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
+; CHECK-LABEL: test4:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: fsrmi a1, 0
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: fsrm a1
+; CHECK-NEXT: #APP
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: ret
+entry:
+ %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %0,
+ <vscale x 1 x float> %1,
+ i64 0, i64 %2)
+ call void asm sideeffect "", ""()
+ %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %a,
+ <vscale x 1 x float> %a,
+ i64 7, i64 %2)
+ ret <vscale x 1 x float> %b
+}
+
+; Test restoring frm before reading frm and doing nothing with following
+; dynamic rounding mode operations.
+declare i32 @llvm.get.rounding()
+define <vscale x 1 x float> @test5(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2, ptr %p) nounwind {
+; CHECK-LABEL: test5:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: fsrmi a0, 0
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: fsrm a0
+; CHECK-NEXT: frrm a0
+; CHECK-NEXT: slli a0, a0, 2
+; CHECK-NEXT: lui a2, 66
+; CHECK-NEXT: addiw a2, a2, 769
+; CHECK-NEXT: srl a0, a2, a0
+; CHECK-NEXT: andi a0, a0, 7
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: sw a0, 0(a1)
+; CHECK-NEXT: ret
+entry:
+ %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %0,
+ <vscale x 1 x float> %1,
+ i64 0, i64 %2)
+ %rm = call i32 @llvm.get.rounding()
+ store i32 %rm, ptr %p, align 4
+ %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32(
+ <vscale x 1 x float> undef,
+ <vscale x 1 x float> %a,
+ <vscale x 1 x float> %a,
+ i64 7, i64 %2)
+ ret <vscale x 1 x float> %b
+}
+
+; Test not set FRM for the two vfadd after WriteFRMImm.
+declare void @llvm.set.rounding(i32)
+define <vscale x 1 x float> @test6(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
+; CHECK-LABEL: test6:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: fsrmi 4
+; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
+; CHECK-NEXT: vfadd.vv v8, v8, v9
+; CHECK-NEXT: vfadd.vv v8, v8, v8
+; CHECK-NEXT: ret
+entry:
----------------
preames wrote:
Please split this into two tests: one for following known same, one for following DYN.
Also please add coverage for the case where the immediate next is known *different* constant.
https://github.com/llvm/llvm-project/pull/77744
More information about the llvm-commits
mailing list