; 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
; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d \
; RUN: -riscv-disable-frm-insert-opt < %s | FileCheck %s --check-prefix=UNOPT
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: fsrmi a1, 0
; 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: fsrm a1
; CHECK-NEXT: ret
;
; UNOPT-LABEL: test:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: fsrmi a0, 0
; UNOPT-NEXT: vfadd.vv v8, v8, v8
; UNOPT-NEXT: fsrm a0
; UNOPT-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: fsrmi a1, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: fsrmi 1
; CHECK-NEXT: vfadd.vv v8, v8, v8
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: ret
;
; UNOPT-LABEL: test2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: fsrmi a0, 1
; UNOPT-NEXT: vfadd.vv v8, v8, v8
; UNOPT-NEXT: fsrm a0
; UNOPT-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
}
declare void @foo()
define <vscale x 1 x float> @just_call(<vscale x 1 x float> %0) nounwind {
; CHECK-LABEL: just_call:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -48
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: sub sp, sp, a0
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: call foo
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 48
; CHECK-NEXT: ret
;
; UNOPT-LABEL: just_call:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: addi sp, sp, -48
; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: sub sp, sp, a0
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; UNOPT-NEXT: call foo
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: add sp, sp, a0
; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; UNOPT-NEXT: addi sp, sp, 48
; UNOPT-NEXT: ret
entry:
call void @foo()
ret <vscale x 1 x float> %0
}
define <vscale x 1 x float> @before_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: before_call1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -48
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: sub sp, sp, a1
; CHECK-NEXT: fsrmi a1, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: call foo
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 48
; CHECK-NEXT: ret
;
; UNOPT-LABEL: before_call1:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: addi sp, sp, -48
; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; UNOPT-NEXT: csrr a1, vlenb
; UNOPT-NEXT: slli a1, a1, 1
; UNOPT-NEXT: sub sp, sp, a1
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: call foo
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: add sp, sp, a0
; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; UNOPT-NEXT: addi sp, sp, 48
; UNOPT-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()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @before_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: before_call2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -48
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: sub sp, sp, a1
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: call foo
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 48
; CHECK-NEXT: ret
;
; UNOPT-LABEL: before_call2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: addi sp, sp, -48
; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; UNOPT-NEXT: csrr a1, vlenb
; UNOPT-NEXT: slli a1, a1, 1
; UNOPT-NEXT: sub sp, sp, a1
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; UNOPT-NEXT: call foo
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: add sp, sp, a0
; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; UNOPT-NEXT: addi sp, sp, 48
; UNOPT-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 7, i64 %2)
call void @foo()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @after_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_call1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -48
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: sub sp, sp, a1
; CHECK-NEXT: fsrmi a1, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: call foo
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 48
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_call1:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: addi sp, sp, -48
; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; UNOPT-NEXT: csrr a1, vlenb
; UNOPT-NEXT: slli a1, a1, 1
; UNOPT-NEXT: sub sp, sp, a1
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: call foo
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: add sp, sp, a0
; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; UNOPT-NEXT: addi sp, sp, 48
; UNOPT-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()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @after_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_call2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi sp, sp, -48
; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; CHECK-NEXT: csrr a1, vlenb
; CHECK-NEXT: slli a1, a1, 1
; CHECK-NEXT: sub sp, sp, a1
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: call foo
; CHECK-NEXT: addi a0, sp, 32
; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; CHECK-NEXT: csrr a0, vlenb
; CHECK-NEXT: slli a0, a0, 1
; CHECK-NEXT: add sp, sp, a0
; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; CHECK-NEXT: addi sp, sp, 48
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_call2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: addi sp, sp, -48
; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
; UNOPT-NEXT: csrr a1, vlenb
; UNOPT-NEXT: slli a1, a1, 1
; UNOPT-NEXT: sub sp, sp, a1
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill
; UNOPT-NEXT: call foo
; UNOPT-NEXT: addi a0, sp, 32
; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload
; UNOPT-NEXT: csrr a0, vlenb
; UNOPT-NEXT: slli a0, a0, 1
; UNOPT-NEXT: add sp, sp, a0
; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
; UNOPT-NEXT: addi sp, sp, 48
; UNOPT-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 7, i64 %2)
call void @foo()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @just_asm(<vscale x 1 x float> %0) nounwind {
; CHECK-LABEL: just_asm:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
;
; UNOPT-LABEL: just_asm:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: #APP
; UNOPT-NEXT: #NO_APP
; UNOPT-NEXT: ret
entry:
call void asm sideeffect "", ""()
ret <vscale x 1 x float> %0
}
define <vscale x 1 x float> @before_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: before_asm1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: fsrmi a1, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
;
; UNOPT-LABEL: before_asm1:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: #APP
; UNOPT-NEXT: #NO_APP
; UNOPT-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 "", ""()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @before_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: before_asm2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
;
; UNOPT-LABEL: before_asm2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: #APP
; UNOPT-NEXT: #NO_APP
; UNOPT-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 7, i64 %2)
call void asm sideeffect "", ""()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @after_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_asm1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: fsrmi a1, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_asm1:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi a1, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: #APP
; UNOPT-NEXT: #NO_APP
; UNOPT-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 "", ""()
ret <vscale x 1 x float> %a
}
define <vscale x 1 x float> @after_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_asm2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: #APP
; CHECK-NEXT: #NO_APP
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_asm2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: #APP
; UNOPT-NEXT: #NO_APP
; UNOPT-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 7, i64 %2)
call void asm sideeffect "", ""()
ret <vscale x 1 x float> %a
}
; Test restoring frm before reading frm and doing nothing with following
; dynamic rounding mode operations.
; TODO: The frrm could be elided.
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: fsrmi a2, 0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: fsrm a2
; 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
;
; UNOPT-LABEL: test5:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi a2, 0
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a2
; UNOPT-NEXT: frrm a0
; UNOPT-NEXT: slli a0, a0, 2
; UNOPT-NEXT: lui a2, 66
; UNOPT-NEXT: addiw a2, a2, 769
; UNOPT-NEXT: srl a0, a2, a0
; UNOPT-NEXT: andi a0, a0, 7
; UNOPT-NEXT: vfadd.vv v8, v8, v8
; UNOPT-NEXT: sw a0, 0(a1)
; UNOPT-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 vfadd with DYN after WriteFRMImm.
declare void @llvm.set.rounding(i32)
define <vscale x 1 x float> @after_fsrm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_fsrm1:
; 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: ret
;
; UNOPT-LABEL: after_fsrm1:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi 4
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: ret
entry:
call void @llvm.set.rounding(i32 4)
%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 7, i64 %2)
ret <vscale x 1 x float> %a
}
; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm.
define <vscale x 1 x float> @after_fsrm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_fsrm2:
; 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: ret
;
; UNOPT-LABEL: after_fsrm2:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi 4
; UNOPT-NEXT: fsrmi a1, 4
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: ret
entry:
call void @llvm.set.rounding(i32 4)
%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 4, i64 %2)
ret <vscale x 1 x float> %a
}
; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm.
define <vscale x 1 x float> @after_fsrm3(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind {
; CHECK-LABEL: after_fsrm3:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: fsrmi 4
; CHECK-NEXT: fsrmi a1, 5
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: fsrm a1
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_fsrm3:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: fsrmi 4
; UNOPT-NEXT: fsrmi a1, 5
; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: fsrm a1
; UNOPT-NEXT: ret
entry:
call void @llvm.set.rounding(i32 4)
%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 5, i64 %2)
ret <vscale x 1 x float> %a
}
; Test not set FRM for the vfadd after WriteFRM.
define <vscale x 1 x float> @after_fsrm4(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i32 %rm, i64 %2) nounwind {
; CHECK-LABEL: after_fsrm4:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: slli a0, a0, 32
; CHECK-NEXT: srli a0, a0, 30
; 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: fsrm a0
; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
; CHECK-NEXT: vfadd.vv v8, v8, v9
; CHECK-NEXT: ret
;
; UNOPT-LABEL: after_fsrm4:
; UNOPT: # %bb.0: # %entry
; UNOPT-NEXT: slli a0, a0, 32
; UNOPT-NEXT: srli a0, a0, 30
; UNOPT-NEXT: lui a2, 66
; UNOPT-NEXT: addiw a2, a2, 769
; UNOPT-NEXT: srl a0, a2, a0
; UNOPT-NEXT: andi a0, a0, 7
; UNOPT-NEXT: fsrm a0
; UNOPT-NEXT: vsetvli zero, a1, e32, mf2, ta, ma
; UNOPT-NEXT: vfadd.vv v8, v8, v9
; UNOPT-NEXT: ret
entry:
call void @llvm.set.rounding(i32 %rm)
%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 7, i64 %2)
ret <vscale x 1 x float> %a
}