1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 2; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d < %s | FileCheck %s 3; RUN: llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs -target-abi=lp64d \ 4; RUN: -riscv-disable-frm-insert-opt < %s | FileCheck %s --check-prefix=UNOPT 5 6declare <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 7 <vscale x 1 x float>, 8 <vscale x 1 x float>, 9 <vscale x 1 x float>, 10 i64, i64) 11 12; Test only save/restore frm once. 13define <vscale x 1 x float> @test(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 14; CHECK-LABEL: test: 15; CHECK: # %bb.0: # %entry 16; CHECK-NEXT: fsrmi a1, 0 17; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 18; CHECK-NEXT: vfadd.vv v8, v8, v9 19; CHECK-NEXT: vfadd.vv v8, v8, v8 20; CHECK-NEXT: fsrm a1 21; CHECK-NEXT: ret 22; 23; UNOPT-LABEL: test: 24; UNOPT: # %bb.0: # %entry 25; UNOPT-NEXT: fsrmi a1, 0 26; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 27; UNOPT-NEXT: vfadd.vv v8, v8, v9 28; UNOPT-NEXT: fsrm a1 29; UNOPT-NEXT: fsrmi a0, 0 30; UNOPT-NEXT: vfadd.vv v8, v8, v8 31; UNOPT-NEXT: fsrm a0 32; UNOPT-NEXT: ret 33entry: 34 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 35 <vscale x 1 x float> undef, 36 <vscale x 1 x float> %0, 37 <vscale x 1 x float> %1, 38 i64 0, i64 %2) 39 %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 40 <vscale x 1 x float> undef, 41 <vscale x 1 x float> %a, 42 <vscale x 1 x float> %a, 43 i64 0, i64 %2) 44 ret <vscale x 1 x float> %b 45} 46 47; Test only restore frm once. 48define <vscale x 1 x float> @test2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 49; CHECK-LABEL: test2: 50; CHECK: # %bb.0: # %entry 51; CHECK-NEXT: fsrmi a1, 0 52; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 53; CHECK-NEXT: vfadd.vv v8, v8, v9 54; CHECK-NEXT: fsrmi 1 55; CHECK-NEXT: vfadd.vv v8, v8, v8 56; CHECK-NEXT: fsrm a1 57; CHECK-NEXT: ret 58; 59; UNOPT-LABEL: test2: 60; UNOPT: # %bb.0: # %entry 61; UNOPT-NEXT: fsrmi a1, 0 62; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 63; UNOPT-NEXT: vfadd.vv v8, v8, v9 64; UNOPT-NEXT: fsrm a1 65; UNOPT-NEXT: fsrmi a0, 1 66; UNOPT-NEXT: vfadd.vv v8, v8, v8 67; UNOPT-NEXT: fsrm a0 68; UNOPT-NEXT: ret 69entry: 70 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 71 <vscale x 1 x float> undef, 72 <vscale x 1 x float> %0, 73 <vscale x 1 x float> %1, 74 i64 0, i64 %2) 75 %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 76 <vscale x 1 x float> undef, 77 <vscale x 1 x float> %a, 78 <vscale x 1 x float> %a, 79 i64 1, i64 %2) 80 ret <vscale x 1 x float> %b 81} 82 83declare void @foo() 84define <vscale x 1 x float> @just_call(<vscale x 1 x float> %0) nounwind { 85; CHECK-LABEL: just_call: 86; CHECK: # %bb.0: # %entry 87; CHECK-NEXT: addi sp, sp, -48 88; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 89; CHECK-NEXT: csrr a0, vlenb 90; CHECK-NEXT: sub sp, sp, a0 91; CHECK-NEXT: addi a0, sp, 32 92; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 93; CHECK-NEXT: call foo 94; CHECK-NEXT: addi a0, sp, 32 95; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 96; CHECK-NEXT: csrr a0, vlenb 97; CHECK-NEXT: add sp, sp, a0 98; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 99; CHECK-NEXT: addi sp, sp, 48 100; CHECK-NEXT: ret 101; 102; UNOPT-LABEL: just_call: 103; UNOPT: # %bb.0: # %entry 104; UNOPT-NEXT: addi sp, sp, -48 105; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 106; UNOPT-NEXT: csrr a0, vlenb 107; UNOPT-NEXT: sub sp, sp, a0 108; UNOPT-NEXT: addi a0, sp, 32 109; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 110; UNOPT-NEXT: call foo 111; UNOPT-NEXT: addi a0, sp, 32 112; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 113; UNOPT-NEXT: csrr a0, vlenb 114; UNOPT-NEXT: add sp, sp, a0 115; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 116; UNOPT-NEXT: addi sp, sp, 48 117; UNOPT-NEXT: ret 118entry: 119 call void @foo() 120 ret <vscale x 1 x float> %0 121} 122 123define <vscale x 1 x float> @before_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 124; CHECK-LABEL: before_call1: 125; CHECK: # %bb.0: # %entry 126; CHECK-NEXT: addi sp, sp, -48 127; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 128; CHECK-NEXT: csrr a1, vlenb 129; CHECK-NEXT: sub sp, sp, a1 130; CHECK-NEXT: fsrmi a1, 0 131; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 132; CHECK-NEXT: vfadd.vv v8, v8, v9 133; CHECK-NEXT: addi a0, sp, 32 134; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 135; CHECK-NEXT: fsrm a1 136; CHECK-NEXT: call foo 137; CHECK-NEXT: addi a0, sp, 32 138; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 139; CHECK-NEXT: csrr a0, vlenb 140; CHECK-NEXT: add sp, sp, a0 141; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 142; CHECK-NEXT: addi sp, sp, 48 143; CHECK-NEXT: ret 144; 145; UNOPT-LABEL: before_call1: 146; UNOPT: # %bb.0: # %entry 147; UNOPT-NEXT: addi sp, sp, -48 148; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 149; UNOPT-NEXT: csrr a1, vlenb 150; UNOPT-NEXT: sub sp, sp, a1 151; UNOPT-NEXT: fsrmi a1, 0 152; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 153; UNOPT-NEXT: vfadd.vv v8, v8, v9 154; UNOPT-NEXT: addi a0, sp, 32 155; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 156; UNOPT-NEXT: fsrm a1 157; UNOPT-NEXT: call foo 158; UNOPT-NEXT: addi a0, sp, 32 159; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 160; UNOPT-NEXT: csrr a0, vlenb 161; UNOPT-NEXT: add sp, sp, a0 162; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 163; UNOPT-NEXT: addi sp, sp, 48 164; UNOPT-NEXT: ret 165entry: 166 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 167 <vscale x 1 x float> undef, 168 <vscale x 1 x float> %0, 169 <vscale x 1 x float> %1, 170 i64 0, i64 %2) 171 call void @foo() 172 ret <vscale x 1 x float> %a 173} 174 175define <vscale x 1 x float> @before_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 176; CHECK-LABEL: before_call2: 177; CHECK: # %bb.0: # %entry 178; CHECK-NEXT: addi sp, sp, -48 179; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 180; CHECK-NEXT: csrr a1, vlenb 181; CHECK-NEXT: sub sp, sp, a1 182; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 183; CHECK-NEXT: vfadd.vv v8, v8, v9 184; CHECK-NEXT: addi a0, sp, 32 185; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 186; CHECK-NEXT: call foo 187; CHECK-NEXT: addi a0, sp, 32 188; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 189; CHECK-NEXT: csrr a0, vlenb 190; CHECK-NEXT: add sp, sp, a0 191; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 192; CHECK-NEXT: addi sp, sp, 48 193; CHECK-NEXT: ret 194; 195; UNOPT-LABEL: before_call2: 196; UNOPT: # %bb.0: # %entry 197; UNOPT-NEXT: addi sp, sp, -48 198; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 199; UNOPT-NEXT: csrr a1, vlenb 200; UNOPT-NEXT: sub sp, sp, a1 201; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 202; UNOPT-NEXT: vfadd.vv v8, v8, v9 203; UNOPT-NEXT: addi a0, sp, 32 204; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 205; UNOPT-NEXT: call foo 206; UNOPT-NEXT: addi a0, sp, 32 207; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 208; UNOPT-NEXT: csrr a0, vlenb 209; UNOPT-NEXT: add sp, sp, a0 210; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 211; UNOPT-NEXT: addi sp, sp, 48 212; UNOPT-NEXT: ret 213entry: 214 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 215 <vscale x 1 x float> undef, 216 <vscale x 1 x float> %0, 217 <vscale x 1 x float> %1, 218 i64 7, i64 %2) 219 call void @foo() 220 ret <vscale x 1 x float> %a 221} 222 223define <vscale x 1 x float> @after_call1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 224; CHECK-LABEL: after_call1: 225; CHECK: # %bb.0: # %entry 226; CHECK-NEXT: addi sp, sp, -48 227; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 228; CHECK-NEXT: csrr a1, vlenb 229; CHECK-NEXT: sub sp, sp, a1 230; CHECK-NEXT: fsrmi a1, 0 231; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 232; CHECK-NEXT: vfadd.vv v8, v8, v9 233; CHECK-NEXT: addi a0, sp, 32 234; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 235; CHECK-NEXT: fsrm a1 236; CHECK-NEXT: call foo 237; CHECK-NEXT: addi a0, sp, 32 238; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 239; CHECK-NEXT: csrr a0, vlenb 240; CHECK-NEXT: add sp, sp, a0 241; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 242; CHECK-NEXT: addi sp, sp, 48 243; CHECK-NEXT: ret 244; 245; UNOPT-LABEL: after_call1: 246; UNOPT: # %bb.0: # %entry 247; UNOPT-NEXT: addi sp, sp, -48 248; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 249; UNOPT-NEXT: csrr a1, vlenb 250; UNOPT-NEXT: sub sp, sp, a1 251; UNOPT-NEXT: fsrmi a1, 0 252; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 253; UNOPT-NEXT: vfadd.vv v8, v8, v9 254; UNOPT-NEXT: addi a0, sp, 32 255; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 256; UNOPT-NEXT: fsrm a1 257; UNOPT-NEXT: call foo 258; UNOPT-NEXT: addi a0, sp, 32 259; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 260; UNOPT-NEXT: csrr a0, vlenb 261; UNOPT-NEXT: add sp, sp, a0 262; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 263; UNOPT-NEXT: addi sp, sp, 48 264; UNOPT-NEXT: ret 265entry: 266 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 267 <vscale x 1 x float> undef, 268 <vscale x 1 x float> %0, 269 <vscale x 1 x float> %1, 270 i64 0, i64 %2) 271 call void @foo() 272 ret <vscale x 1 x float> %a 273} 274 275define <vscale x 1 x float> @after_call2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 276; CHECK-LABEL: after_call2: 277; CHECK: # %bb.0: # %entry 278; CHECK-NEXT: addi sp, sp, -48 279; CHECK-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 280; CHECK-NEXT: csrr a1, vlenb 281; CHECK-NEXT: sub sp, sp, a1 282; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 283; CHECK-NEXT: vfadd.vv v8, v8, v9 284; CHECK-NEXT: addi a0, sp, 32 285; CHECK-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 286; CHECK-NEXT: call foo 287; CHECK-NEXT: addi a0, sp, 32 288; CHECK-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 289; CHECK-NEXT: csrr a0, vlenb 290; CHECK-NEXT: add sp, sp, a0 291; CHECK-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 292; CHECK-NEXT: addi sp, sp, 48 293; CHECK-NEXT: ret 294; 295; UNOPT-LABEL: after_call2: 296; UNOPT: # %bb.0: # %entry 297; UNOPT-NEXT: addi sp, sp, -48 298; UNOPT-NEXT: sd ra, 40(sp) # 8-byte Folded Spill 299; UNOPT-NEXT: csrr a1, vlenb 300; UNOPT-NEXT: sub sp, sp, a1 301; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 302; UNOPT-NEXT: vfadd.vv v8, v8, v9 303; UNOPT-NEXT: addi a0, sp, 32 304; UNOPT-NEXT: vs1r.v v8, (a0) # Unknown-size Folded Spill 305; UNOPT-NEXT: call foo 306; UNOPT-NEXT: addi a0, sp, 32 307; UNOPT-NEXT: vl1r.v v8, (a0) # Unknown-size Folded Reload 308; UNOPT-NEXT: csrr a0, vlenb 309; UNOPT-NEXT: add sp, sp, a0 310; UNOPT-NEXT: ld ra, 40(sp) # 8-byte Folded Reload 311; UNOPT-NEXT: addi sp, sp, 48 312; UNOPT-NEXT: ret 313entry: 314 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 315 <vscale x 1 x float> undef, 316 <vscale x 1 x float> %0, 317 <vscale x 1 x float> %1, 318 i64 7, i64 %2) 319 call void @foo() 320 ret <vscale x 1 x float> %a 321} 322 323define <vscale x 1 x float> @just_asm(<vscale x 1 x float> %0) nounwind { 324; CHECK-LABEL: just_asm: 325; CHECK: # %bb.0: # %entry 326; CHECK-NEXT: #APP 327; CHECK-NEXT: #NO_APP 328; CHECK-NEXT: ret 329; 330; UNOPT-LABEL: just_asm: 331; UNOPT: # %bb.0: # %entry 332; UNOPT-NEXT: #APP 333; UNOPT-NEXT: #NO_APP 334; UNOPT-NEXT: ret 335entry: 336 call void asm sideeffect "", ""() 337 ret <vscale x 1 x float> %0 338} 339 340define <vscale x 1 x float> @before_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 341; CHECK-LABEL: before_asm1: 342; CHECK: # %bb.0: # %entry 343; CHECK-NEXT: fsrmi a1, 0 344; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 345; CHECK-NEXT: vfadd.vv v8, v8, v9 346; CHECK-NEXT: fsrm a1 347; CHECK-NEXT: #APP 348; CHECK-NEXT: #NO_APP 349; CHECK-NEXT: ret 350; 351; UNOPT-LABEL: before_asm1: 352; UNOPT: # %bb.0: # %entry 353; UNOPT-NEXT: fsrmi a1, 0 354; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 355; UNOPT-NEXT: vfadd.vv v8, v8, v9 356; UNOPT-NEXT: fsrm a1 357; UNOPT-NEXT: #APP 358; UNOPT-NEXT: #NO_APP 359; UNOPT-NEXT: ret 360entry: 361 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 362 <vscale x 1 x float> undef, 363 <vscale x 1 x float> %0, 364 <vscale x 1 x float> %1, 365 i64 0, i64 %2) 366 call void asm sideeffect "", ""() 367 ret <vscale x 1 x float> %a 368} 369 370define <vscale x 1 x float> @before_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 371; CHECK-LABEL: before_asm2: 372; CHECK: # %bb.0: # %entry 373; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 374; CHECK-NEXT: vfadd.vv v8, v8, v9 375; CHECK-NEXT: #APP 376; CHECK-NEXT: #NO_APP 377; CHECK-NEXT: ret 378; 379; UNOPT-LABEL: before_asm2: 380; UNOPT: # %bb.0: # %entry 381; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 382; UNOPT-NEXT: vfadd.vv v8, v8, v9 383; UNOPT-NEXT: #APP 384; UNOPT-NEXT: #NO_APP 385; UNOPT-NEXT: ret 386entry: 387 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 388 <vscale x 1 x float> undef, 389 <vscale x 1 x float> %0, 390 <vscale x 1 x float> %1, 391 i64 7, i64 %2) 392 call void asm sideeffect "", ""() 393 ret <vscale x 1 x float> %a 394} 395 396define <vscale x 1 x float> @after_asm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 397; CHECK-LABEL: after_asm1: 398; CHECK: # %bb.0: # %entry 399; CHECK-NEXT: fsrmi a1, 0 400; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 401; CHECK-NEXT: vfadd.vv v8, v8, v9 402; CHECK-NEXT: fsrm a1 403; CHECK-NEXT: #APP 404; CHECK-NEXT: #NO_APP 405; CHECK-NEXT: ret 406; 407; UNOPT-LABEL: after_asm1: 408; UNOPT: # %bb.0: # %entry 409; UNOPT-NEXT: fsrmi a1, 0 410; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 411; UNOPT-NEXT: vfadd.vv v8, v8, v9 412; UNOPT-NEXT: fsrm a1 413; UNOPT-NEXT: #APP 414; UNOPT-NEXT: #NO_APP 415; UNOPT-NEXT: ret 416entry: 417 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 418 <vscale x 1 x float> undef, 419 <vscale x 1 x float> %0, 420 <vscale x 1 x float> %1, 421 i64 0, i64 %2) 422 call void asm sideeffect "", ""() 423 ret <vscale x 1 x float> %a 424} 425 426define <vscale x 1 x float> @after_asm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 427; CHECK-LABEL: after_asm2: 428; CHECK: # %bb.0: # %entry 429; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 430; CHECK-NEXT: vfadd.vv v8, v8, v9 431; CHECK-NEXT: #APP 432; CHECK-NEXT: #NO_APP 433; CHECK-NEXT: ret 434; 435; UNOPT-LABEL: after_asm2: 436; UNOPT: # %bb.0: # %entry 437; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 438; UNOPT-NEXT: vfadd.vv v8, v8, v9 439; UNOPT-NEXT: #APP 440; UNOPT-NEXT: #NO_APP 441; UNOPT-NEXT: ret 442entry: 443 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 444 <vscale x 1 x float> undef, 445 <vscale x 1 x float> %0, 446 <vscale x 1 x float> %1, 447 i64 7, i64 %2) 448 call void asm sideeffect "", ""() 449 ret <vscale x 1 x float> %a 450} 451 452; Test restoring frm before reading frm and doing nothing with following 453; dynamic rounding mode operations. 454; TODO: The frrm could be elided. 455declare i32 @llvm.get.rounding() 456define <vscale x 1 x float> @test5(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2, ptr %p) nounwind { 457; CHECK-LABEL: test5: 458; CHECK: # %bb.0: # %entry 459; CHECK-NEXT: fsrmi a2, 0 460; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 461; CHECK-NEXT: vfadd.vv v8, v8, v9 462; CHECK-NEXT: lui a0, 66 463; CHECK-NEXT: fsrm a2 464; CHECK-NEXT: addiw a0, a0, 769 465; CHECK-NEXT: frrm a2 466; CHECK-NEXT: slli a2, a2, 2 467; CHECK-NEXT: srl a0, a0, a2 468; CHECK-NEXT: andi a0, a0, 7 469; CHECK-NEXT: vfadd.vv v8, v8, v8 470; CHECK-NEXT: sw a0, 0(a1) 471; CHECK-NEXT: ret 472; 473; UNOPT-LABEL: test5: 474; UNOPT: # %bb.0: # %entry 475; UNOPT-NEXT: fsrmi a2, 0 476; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 477; UNOPT-NEXT: vfadd.vv v8, v8, v9 478; UNOPT-NEXT: lui a0, 66 479; UNOPT-NEXT: fsrm a2 480; UNOPT-NEXT: addiw a0, a0, 769 481; UNOPT-NEXT: frrm a2 482; UNOPT-NEXT: slli a2, a2, 2 483; UNOPT-NEXT: srl a0, a0, a2 484; UNOPT-NEXT: andi a0, a0, 7 485; UNOPT-NEXT: vfadd.vv v8, v8, v8 486; UNOPT-NEXT: sw a0, 0(a1) 487; UNOPT-NEXT: ret 488entry: 489 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 490 <vscale x 1 x float> undef, 491 <vscale x 1 x float> %0, 492 <vscale x 1 x float> %1, 493 i64 0, i64 %2) 494 %rm = call i32 @llvm.get.rounding() 495 store i32 %rm, ptr %p, align 4 496 %b = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 497 <vscale x 1 x float> undef, 498 <vscale x 1 x float> %a, 499 <vscale x 1 x float> %a, 500 i64 7, i64 %2) 501 ret <vscale x 1 x float> %b 502} 503 504; Test not set FRM for vfadd with DYN after WriteFRMImm. 505declare void @llvm.set.rounding(i32) 506define <vscale x 1 x float> @after_fsrm1(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 507; CHECK-LABEL: after_fsrm1: 508; CHECK: # %bb.0: # %entry 509; CHECK-NEXT: fsrmi 4 510; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 511; CHECK-NEXT: vfadd.vv v8, v8, v9 512; CHECK-NEXT: ret 513; 514; UNOPT-LABEL: after_fsrm1: 515; UNOPT: # %bb.0: # %entry 516; UNOPT-NEXT: fsrmi 4 517; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 518; UNOPT-NEXT: vfadd.vv v8, v8, v9 519; UNOPT-NEXT: ret 520entry: 521 call void @llvm.set.rounding(i32 4) 522 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 523 <vscale x 1 x float> undef, 524 <vscale x 1 x float> %0, 525 <vscale x 1 x float> %1, 526 i64 7, i64 %2) 527 ret <vscale x 1 x float> %a 528} 529 530; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm. 531define <vscale x 1 x float> @after_fsrm2(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 532; CHECK-LABEL: after_fsrm2: 533; CHECK: # %bb.0: # %entry 534; CHECK-NEXT: fsrmi 4 535; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 536; CHECK-NEXT: vfadd.vv v8, v8, v9 537; CHECK-NEXT: ret 538; 539; UNOPT-LABEL: after_fsrm2: 540; UNOPT: # %bb.0: # %entry 541; UNOPT-NEXT: fsrmi 4 542; UNOPT-NEXT: fsrmi a1, 4 543; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 544; UNOPT-NEXT: vfadd.vv v8, v8, v9 545; UNOPT-NEXT: fsrm a1 546; UNOPT-NEXT: ret 547entry: 548 call void @llvm.set.rounding(i32 4) 549 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 550 <vscale x 1 x float> undef, 551 <vscale x 1 x float> %0, 552 <vscale x 1 x float> %1, 553 i64 4, i64 %2) 554 ret <vscale x 1 x float> %a 555} 556 557; Test not set FRM for vfadd with a known rm after WriteFRMImm with same rm. 558define <vscale x 1 x float> @after_fsrm3(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i64 %2) nounwind { 559; CHECK-LABEL: after_fsrm3: 560; CHECK: # %bb.0: # %entry 561; CHECK-NEXT: fsrmi 4 562; CHECK-NEXT: fsrmi a1, 3 563; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 564; CHECK-NEXT: vfadd.vv v8, v8, v9 565; CHECK-NEXT: fsrm a1 566; CHECK-NEXT: ret 567; 568; UNOPT-LABEL: after_fsrm3: 569; UNOPT: # %bb.0: # %entry 570; UNOPT-NEXT: fsrmi 4 571; UNOPT-NEXT: fsrmi a1, 3 572; UNOPT-NEXT: vsetvli zero, a0, e32, mf2, ta, ma 573; UNOPT-NEXT: vfadd.vv v8, v8, v9 574; UNOPT-NEXT: fsrm a1 575; UNOPT-NEXT: ret 576entry: 577 call void @llvm.set.rounding(i32 4) 578 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 579 <vscale x 1 x float> undef, 580 <vscale x 1 x float> %0, 581 <vscale x 1 x float> %1, 582 i64 3, i64 %2) 583 ret <vscale x 1 x float> %a 584} 585 586; Test not set FRM for the vfadd after WriteFRM. 587define <vscale x 1 x float> @after_fsrm4(<vscale x 1 x float> %0, <vscale x 1 x float> %1, i32 %rm, i64 %2) nounwind { 588; CHECK-LABEL: after_fsrm4: 589; CHECK: # %bb.0: # %entry 590; CHECK-NEXT: slli a0, a0, 32 591; CHECK-NEXT: lui a2, 66 592; CHECK-NEXT: srli a0, a0, 30 593; CHECK-NEXT: addiw a2, a2, 769 594; CHECK-NEXT: srl a0, a2, a0 595; CHECK-NEXT: andi a0, a0, 7 596; CHECK-NEXT: fsrm a0 597; CHECK-NEXT: vsetvli zero, a1, e32, mf2, ta, ma 598; CHECK-NEXT: vfadd.vv v8, v8, v9 599; CHECK-NEXT: ret 600; 601; UNOPT-LABEL: after_fsrm4: 602; UNOPT: # %bb.0: # %entry 603; UNOPT-NEXT: slli a0, a0, 32 604; UNOPT-NEXT: lui a2, 66 605; UNOPT-NEXT: srli a0, a0, 30 606; UNOPT-NEXT: addiw a2, a2, 769 607; UNOPT-NEXT: srl a0, a2, a0 608; UNOPT-NEXT: andi a0, a0, 7 609; UNOPT-NEXT: fsrm a0 610; UNOPT-NEXT: vsetvli zero, a1, e32, mf2, ta, ma 611; UNOPT-NEXT: vfadd.vv v8, v8, v9 612; UNOPT-NEXT: ret 613entry: 614 call void @llvm.set.rounding(i32 %rm) 615 %a = call <vscale x 1 x float> @llvm.riscv.vfadd.nxv1f32.nxv1f32( 616 <vscale x 1 x float> undef, 617 <vscale x 1 x float> %0, 618 <vscale x 1 x float> %1, 619 i64 7, i64 %2) 620 ret <vscale x 1 x float> %a 621} 622