; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( , , , i64, i64) ; Test only save/restore frm once. define @test( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) %b = call @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %a, %a, i64 0, i64 %2) ret %b } ; Test only restore frm once. define @test2( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) %b = call @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %a, %a, i64 1, i64 %2) ret %b } declare void @foo() define @just_call( %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: sub sp, sp, a0 ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vs1r.v v8, (a0) # vscale x 8-byte Folded Spill ; CHECK-NEXT: call foo ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; CHECK-NEXT: csrr a0, vlenb ; 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: sub sp, sp, a0 ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vs1r.v v8, (a0) # vscale x 8-byte Folded Spill ; UNOPT-NEXT: call foo ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; UNOPT-NEXT: csrr a0, vlenb ; 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 %0 } define @before_call1( %0, %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: 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) # vscale x 8-byte Folded Spill ; CHECK-NEXT: fsrm a1 ; CHECK-NEXT: call foo ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; CHECK-NEXT: csrr a0, vlenb ; 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: 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) # vscale x 8-byte Folded Spill ; UNOPT-NEXT: fsrm a1 ; UNOPT-NEXT: call foo ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; UNOPT-NEXT: csrr a0, vlenb ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) call void @foo() ret %a } define @before_call2( %0, %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: 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) # vscale x 8-byte Folded Spill ; CHECK-NEXT: call foo ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; CHECK-NEXT: csrr a0, vlenb ; 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: 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) # vscale x 8-byte Folded Spill ; UNOPT-NEXT: call foo ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; UNOPT-NEXT: csrr a0, vlenb ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) call void @foo() ret %a } define @after_call1( %0, %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: 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) # vscale x 8-byte Folded Spill ; CHECK-NEXT: fsrm a1 ; CHECK-NEXT: call foo ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; CHECK-NEXT: csrr a0, vlenb ; 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: 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) # vscale x 8-byte Folded Spill ; UNOPT-NEXT: fsrm a1 ; UNOPT-NEXT: call foo ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; UNOPT-NEXT: csrr a0, vlenb ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) call void @foo() ret %a } define @after_call2( %0, %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: 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) # vscale x 8-byte Folded Spill ; CHECK-NEXT: call foo ; CHECK-NEXT: addi a0, sp, 32 ; CHECK-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; CHECK-NEXT: csrr a0, vlenb ; 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: 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) # vscale x 8-byte Folded Spill ; UNOPT-NEXT: call foo ; UNOPT-NEXT: addi a0, sp, 32 ; UNOPT-NEXT: vl1r.v v8, (a0) # vscale x 8-byte Folded Reload ; UNOPT-NEXT: csrr a0, vlenb ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) call void @foo() ret %a } define @just_asm( %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 %0 } define @before_asm1( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) call void asm sideeffect "", ""() ret %a } define @before_asm2( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) call void asm sideeffect "", ""() ret %a } define @after_asm1( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) call void asm sideeffect "", ""() ret %a } define @after_asm2( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) call void asm sideeffect "", ""() ret %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 @test5( %0, %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: lui a0, 66 ; CHECK-NEXT: fsrm a2 ; CHECK-NEXT: addi a0, a0, 769 ; CHECK-NEXT: frrm a2 ; CHECK-NEXT: slli a2, a2, 2 ; CHECK-NEXT: srl a0, a0, a2 ; 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: lui a0, 66 ; UNOPT-NEXT: fsrm a2 ; UNOPT-NEXT: addi a0, a0, 769 ; UNOPT-NEXT: frrm a2 ; UNOPT-NEXT: slli a2, a2, 2 ; UNOPT-NEXT: srl a0, a0, a2 ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 0, i64 %2) %rm = call i32 @llvm.get.rounding() store i32 %rm, ptr %p, align 4 %b = call @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %a, %a, i64 7, i64 %2) ret %b } ; Test not set FRM for vfadd with DYN after WriteFRMImm. declare void @llvm.set.rounding(i32) define @after_fsrm1( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) ret %a } ; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm. define @after_fsrm2( %0, %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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 4, i64 %2) ret %a } ; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm. define @after_fsrm3( %0, %1, i64 %2) nounwind { ; CHECK-LABEL: after_fsrm3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: fsrmi 4 ; CHECK-NEXT: fsrmi a1, 3 ; 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, 3 ; 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 3, i64 %2) ret %a } ; Test not set FRM for the vfadd after WriteFRM. define @after_fsrm4( %0, %1, i32 %rm, i64 %2) nounwind { ; CHECK-LABEL: after_fsrm4: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: slli a0, a0, 32 ; CHECK-NEXT: lui a2, 66 ; CHECK-NEXT: srli a0, a0, 30 ; CHECK-NEXT: addi 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: lui a2, 66 ; UNOPT-NEXT: srli a0, a0, 30 ; UNOPT-NEXT: addi 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 @llvm.riscv.vfadd.nxv1f32.nxv1f32( poison, %0, %1, i64 7, i64 %2) ret %a }