625 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple riscv32 -enable-shrink-wrap=false < %s \3; RUN: | FileCheck %s -check-prefix=RV32I-SW-NO4; RUN: llc -mtriple riscv32 < %s \5; RUN: | FileCheck %s -check-prefix=RV32I-SW6; RUN: llc -mtriple riscv32 -mattr=+save-restore < %s \7; RUN: | FileCheck %s -check-prefix=RV32I-SW-SR8; RUN: llc -mtriple riscv64 < %s \9; RUN: | FileCheck %s -check-prefix=RV64I-SW10 11declare void @abort()12 13define void @eliminate_restore(i32 %n) nounwind {14; RV32I-SW-NO-LABEL: eliminate_restore:15; RV32I-SW-NO: # %bb.0:16; RV32I-SW-NO-NEXT: addi sp, sp, -1617; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill18; RV32I-SW-NO-NEXT: li a1, 3219; RV32I-SW-NO-NEXT: bgeu a1, a0, .LBB0_220; RV32I-SW-NO-NEXT: # %bb.1: # %if.end21; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload22; RV32I-SW-NO-NEXT: addi sp, sp, 1623; RV32I-SW-NO-NEXT: ret24; RV32I-SW-NO-NEXT: .LBB0_2: # %if.then25; RV32I-SW-NO-NEXT: call abort26;27; RV32I-SW-LABEL: eliminate_restore:28; RV32I-SW: # %bb.0:29; RV32I-SW-NEXT: li a1, 3230; RV32I-SW-NEXT: bgeu a1, a0, .LBB0_231; RV32I-SW-NEXT: # %bb.1: # %if.end32; RV32I-SW-NEXT: ret33; RV32I-SW-NEXT: .LBB0_2: # %if.then34; RV32I-SW-NEXT: addi sp, sp, -1635; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill36; RV32I-SW-NEXT: call abort37;38; RV32I-SW-SR-LABEL: eliminate_restore:39; RV32I-SW-SR: # %bb.0:40; RV32I-SW-SR-NEXT: li a1, 3241; RV32I-SW-SR-NEXT: bgeu a1, a0, .LBB0_242; RV32I-SW-SR-NEXT: # %bb.1: # %if.end43; RV32I-SW-SR-NEXT: ret44; RV32I-SW-SR-NEXT: .LBB0_2: # %if.then45; RV32I-SW-SR-NEXT: call t0, __riscv_save_046; RV32I-SW-SR-NEXT: call abort47;48; RV64I-SW-LABEL: eliminate_restore:49; RV64I-SW: # %bb.0:50; RV64I-SW-NEXT: sext.w a0, a051; RV64I-SW-NEXT: li a1, 3252; RV64I-SW-NEXT: bgeu a1, a0, .LBB0_253; RV64I-SW-NEXT: # %bb.1: # %if.end54; RV64I-SW-NEXT: ret55; RV64I-SW-NEXT: .LBB0_2: # %if.then56; RV64I-SW-NEXT: addi sp, sp, -1657; RV64I-SW-NEXT: sd ra, 8(sp) # 8-byte Folded Spill58; RV64I-SW-NEXT: call abort59 %cmp = icmp ule i32 %n, 3260 br i1 %cmp, label %if.then, label %if.end61 62if.then:63 call void @abort()64 unreachable65 66if.end:67 ret void68}69 70declare void @notdead(ptr)71 72define void @conditional_alloca(i32 %n) nounwind {73; RV32I-SW-NO-LABEL: conditional_alloca:74; RV32I-SW-NO: # %bb.0:75; RV32I-SW-NO-NEXT: addi sp, sp, -1676; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill77; RV32I-SW-NO-NEXT: sw s0, 8(sp) # 4-byte Folded Spill78; RV32I-SW-NO-NEXT: addi s0, sp, 1679; RV32I-SW-NO-NEXT: li a1, 3280; RV32I-SW-NO-NEXT: bltu a1, a0, .LBB1_281; RV32I-SW-NO-NEXT: # %bb.1: # %if.then82; RV32I-SW-NO-NEXT: addi a0, a0, 1583; RV32I-SW-NO-NEXT: andi a0, a0, -1684; RV32I-SW-NO-NEXT: sub a0, sp, a085; RV32I-SW-NO-NEXT: mv sp, a086; RV32I-SW-NO-NEXT: call notdead87; RV32I-SW-NO-NEXT: .LBB1_2: # %if.end88; RV32I-SW-NO-NEXT: addi sp, s0, -1689; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload90; RV32I-SW-NO-NEXT: lw s0, 8(sp) # 4-byte Folded Reload91; RV32I-SW-NO-NEXT: addi sp, sp, 1692; RV32I-SW-NO-NEXT: ret93;94; RV32I-SW-LABEL: conditional_alloca:95; RV32I-SW: # %bb.0:96; RV32I-SW-NEXT: li a1, 3297; RV32I-SW-NEXT: bltu a1, a0, .LBB1_298; RV32I-SW-NEXT: # %bb.1: # %if.then99; RV32I-SW-NEXT: addi sp, sp, -16100; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill101; RV32I-SW-NEXT: sw s0, 8(sp) # 4-byte Folded Spill102; RV32I-SW-NEXT: addi s0, sp, 16103; RV32I-SW-NEXT: addi a0, a0, 15104; RV32I-SW-NEXT: andi a0, a0, -16105; RV32I-SW-NEXT: sub a0, sp, a0106; RV32I-SW-NEXT: mv sp, a0107; RV32I-SW-NEXT: call notdead108; RV32I-SW-NEXT: addi sp, s0, -16109; RV32I-SW-NEXT: lw ra, 12(sp) # 4-byte Folded Reload110; RV32I-SW-NEXT: lw s0, 8(sp) # 4-byte Folded Reload111; RV32I-SW-NEXT: addi sp, sp, 16112; RV32I-SW-NEXT: .LBB1_2: # %if.end113; RV32I-SW-NEXT: ret114;115; RV32I-SW-SR-LABEL: conditional_alloca:116; RV32I-SW-SR: # %bb.0:117; RV32I-SW-SR-NEXT: li a1, 32118; RV32I-SW-SR-NEXT: bltu a1, a0, .LBB1_2119; RV32I-SW-SR-NEXT: # %bb.1: # %if.then120; RV32I-SW-SR-NEXT: call t0, __riscv_save_1121; RV32I-SW-SR-NEXT: addi s0, sp, 16122; RV32I-SW-SR-NEXT: addi a0, a0, 15123; RV32I-SW-SR-NEXT: andi a0, a0, -16124; RV32I-SW-SR-NEXT: sub a0, sp, a0125; RV32I-SW-SR-NEXT: mv sp, a0126; RV32I-SW-SR-NEXT: call notdead127; RV32I-SW-SR-NEXT: addi sp, s0, -16128; RV32I-SW-SR-NEXT: tail __riscv_restore_1129; RV32I-SW-SR-NEXT: .LBB1_2: # %if.end130; RV32I-SW-SR-NEXT: ret131;132; RV64I-SW-LABEL: conditional_alloca:133; RV64I-SW: # %bb.0:134; RV64I-SW-NEXT: sext.w a1, a0135; RV64I-SW-NEXT: li a2, 32136; RV64I-SW-NEXT: bltu a2, a1, .LBB1_2137; RV64I-SW-NEXT: # %bb.1: # %if.then138; RV64I-SW-NEXT: addi sp, sp, -16139; RV64I-SW-NEXT: sd ra, 8(sp) # 8-byte Folded Spill140; RV64I-SW-NEXT: sd s0, 0(sp) # 8-byte Folded Spill141; RV64I-SW-NEXT: addi s0, sp, 16142; RV64I-SW-NEXT: slli a0, a0, 32143; RV64I-SW-NEXT: srli a0, a0, 32144; RV64I-SW-NEXT: addi a0, a0, 15145; RV64I-SW-NEXT: andi a0, a0, -16146; RV64I-SW-NEXT: sub a0, sp, a0147; RV64I-SW-NEXT: mv sp, a0148; RV64I-SW-NEXT: call notdead149; RV64I-SW-NEXT: addi sp, s0, -16150; RV64I-SW-NEXT: ld ra, 8(sp) # 8-byte Folded Reload151; RV64I-SW-NEXT: ld s0, 0(sp) # 8-byte Folded Reload152; RV64I-SW-NEXT: addi sp, sp, 16153; RV64I-SW-NEXT: .LBB1_2: # %if.end154; RV64I-SW-NEXT: ret155 %cmp = icmp ule i32 %n, 32156 br i1 %cmp, label %if.then, label %if.end157 158if.then:159 %addr = alloca i8, i32 %n160 call void @notdead(ptr %addr)161 br label %if.end162 163if.end:164 ret void165}166 167; FIXME: Rematerialize "li s1, 57" for the second use instead of spilling s1,168; and then shrink wrap the result avoiding frame setup on the %bb.0 -> %exit169; edge.170define void @li_straightline_a(i32 zeroext %a, i32 zeroext %b) {171; RV32I-SW-NO-LABEL: li_straightline_a:172; RV32I-SW-NO: # %bb.0:173; RV32I-SW-NO-NEXT: addi sp, sp, -16174; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 16175; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill176; RV32I-SW-NO-NEXT: sw s0, 8(sp) # 4-byte Folded Spill177; RV32I-SW-NO-NEXT: sw s1, 4(sp) # 4-byte Folded Spill178; RV32I-SW-NO-NEXT: .cfi_offset ra, -4179; RV32I-SW-NO-NEXT: .cfi_offset s0, -8180; RV32I-SW-NO-NEXT: .cfi_offset s1, -12181; RV32I-SW-NO-NEXT: li s1, 57182; RV32I-SW-NO-NEXT: beq a0, s1, .LBB2_3183; RV32I-SW-NO-NEXT: # %bb.1: # %do_call184; RV32I-SW-NO-NEXT: mv s0, a1185; RV32I-SW-NO-NEXT: call foo186; RV32I-SW-NO-NEXT: beq s0, s1, .LBB2_3187; RV32I-SW-NO-NEXT: # %bb.2: # %do_call2188; RV32I-SW-NO-NEXT: call foo189; RV32I-SW-NO-NEXT: .LBB2_3: # %exit190; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload191; RV32I-SW-NO-NEXT: lw s0, 8(sp) # 4-byte Folded Reload192; RV32I-SW-NO-NEXT: lw s1, 4(sp) # 4-byte Folded Reload193; RV32I-SW-NO-NEXT: .cfi_restore ra194; RV32I-SW-NO-NEXT: .cfi_restore s0195; RV32I-SW-NO-NEXT: .cfi_restore s1196; RV32I-SW-NO-NEXT: addi sp, sp, 16197; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 0198; RV32I-SW-NO-NEXT: ret199;200; RV32I-SW-LABEL: li_straightline_a:201; RV32I-SW: # %bb.0:202; RV32I-SW-NEXT: addi sp, sp, -16203; RV32I-SW-NEXT: .cfi_def_cfa_offset 16204; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill205; RV32I-SW-NEXT: sw s0, 8(sp) # 4-byte Folded Spill206; RV32I-SW-NEXT: sw s1, 4(sp) # 4-byte Folded Spill207; RV32I-SW-NEXT: .cfi_offset ra, -4208; RV32I-SW-NEXT: .cfi_offset s0, -8209; RV32I-SW-NEXT: .cfi_offset s1, -12210; RV32I-SW-NEXT: li s1, 57211; RV32I-SW-NEXT: beq a0, s1, .LBB2_3212; RV32I-SW-NEXT: # %bb.1: # %do_call213; RV32I-SW-NEXT: mv s0, a1214; RV32I-SW-NEXT: call foo215; RV32I-SW-NEXT: beq s0, s1, .LBB2_3216; RV32I-SW-NEXT: # %bb.2: # %do_call2217; RV32I-SW-NEXT: call foo218; RV32I-SW-NEXT: .LBB2_3: # %exit219; RV32I-SW-NEXT: lw ra, 12(sp) # 4-byte Folded Reload220; RV32I-SW-NEXT: lw s0, 8(sp) # 4-byte Folded Reload221; RV32I-SW-NEXT: lw s1, 4(sp) # 4-byte Folded Reload222; RV32I-SW-NEXT: .cfi_restore ra223; RV32I-SW-NEXT: .cfi_restore s0224; RV32I-SW-NEXT: .cfi_restore s1225; RV32I-SW-NEXT: addi sp, sp, 16226; RV32I-SW-NEXT: .cfi_def_cfa_offset 0227; RV32I-SW-NEXT: ret228;229; RV32I-SW-SR-LABEL: li_straightline_a:230; RV32I-SW-SR: # %bb.0:231; RV32I-SW-SR-NEXT: call t0, __riscv_save_2232; RV32I-SW-SR-NEXT: .cfi_def_cfa_offset 16233; RV32I-SW-SR-NEXT: .cfi_offset ra, -4234; RV32I-SW-SR-NEXT: .cfi_offset s0, -8235; RV32I-SW-SR-NEXT: .cfi_offset s1, -12236; RV32I-SW-SR-NEXT: li s1, 57237; RV32I-SW-SR-NEXT: beq a0, s1, .LBB2_3238; RV32I-SW-SR-NEXT: # %bb.1: # %do_call239; RV32I-SW-SR-NEXT: mv s0, a1240; RV32I-SW-SR-NEXT: call foo241; RV32I-SW-SR-NEXT: beq s0, s1, .LBB2_3242; RV32I-SW-SR-NEXT: # %bb.2: # %do_call2243; RV32I-SW-SR-NEXT: call foo244; RV32I-SW-SR-NEXT: .LBB2_3: # %exit245; RV32I-SW-SR-NEXT: tail __riscv_restore_2246;247; RV64I-SW-LABEL: li_straightline_a:248; RV64I-SW: # %bb.0:249; RV64I-SW-NEXT: addi sp, sp, -32250; RV64I-SW-NEXT: .cfi_def_cfa_offset 32251; RV64I-SW-NEXT: sd ra, 24(sp) # 8-byte Folded Spill252; RV64I-SW-NEXT: sd s0, 16(sp) # 8-byte Folded Spill253; RV64I-SW-NEXT: sd s1, 8(sp) # 8-byte Folded Spill254; RV64I-SW-NEXT: .cfi_offset ra, -8255; RV64I-SW-NEXT: .cfi_offset s0, -16256; RV64I-SW-NEXT: .cfi_offset s1, -24257; RV64I-SW-NEXT: li s1, 57258; RV64I-SW-NEXT: beq a0, s1, .LBB2_3259; RV64I-SW-NEXT: # %bb.1: # %do_call260; RV64I-SW-NEXT: mv s0, a1261; RV64I-SW-NEXT: call foo262; RV64I-SW-NEXT: beq s0, s1, .LBB2_3263; RV64I-SW-NEXT: # %bb.2: # %do_call2264; RV64I-SW-NEXT: call foo265; RV64I-SW-NEXT: .LBB2_3: # %exit266; RV64I-SW-NEXT: ld ra, 24(sp) # 8-byte Folded Reload267; RV64I-SW-NEXT: ld s0, 16(sp) # 8-byte Folded Reload268; RV64I-SW-NEXT: ld s1, 8(sp) # 8-byte Folded Reload269; RV64I-SW-NEXT: .cfi_restore ra270; RV64I-SW-NEXT: .cfi_restore s0271; RV64I-SW-NEXT: .cfi_restore s1272; RV64I-SW-NEXT: addi sp, sp, 32273; RV64I-SW-NEXT: .cfi_def_cfa_offset 0274; RV64I-SW-NEXT: ret275 %cmp0 = icmp eq i32 %a, 57276 br i1 %cmp0, label %exit, label %do_call277do_call:278 call i32 @foo()279 %cmp1 = icmp eq i32 %b, 57280 br i1 %cmp1, label %exit, label %do_call2281do_call2:282 call i32 @foo()283 br label %exit284exit:285 ret void286}287 288; FIXME: The "mv s0, a1" is only required along the do_call path, and can289; be sunk there. We can also shrink wrap to avoid the frame setup along290; the %bb.0 -> %exit edge.291define void @li_straightline_b(i32 zeroext %a, i32 zeroext %b) {292; RV32I-SW-NO-LABEL: li_straightline_b:293; RV32I-SW-NO: # %bb.0:294; RV32I-SW-NO-NEXT: addi sp, sp, -16295; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 16296; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill297; RV32I-SW-NO-NEXT: sw s0, 8(sp) # 4-byte Folded Spill298; RV32I-SW-NO-NEXT: .cfi_offset ra, -4299; RV32I-SW-NO-NEXT: .cfi_offset s0, -8300; RV32I-SW-NO-NEXT: mv s0, a1301; RV32I-SW-NO-NEXT: li a1, 57302; RV32I-SW-NO-NEXT: beq a0, a1, .LBB3_3303; RV32I-SW-NO-NEXT: # %bb.1: # %do_call304; RV32I-SW-NO-NEXT: call foo305; RV32I-SW-NO-NEXT: li a0, 57306; RV32I-SW-NO-NEXT: beq s0, a0, .LBB3_3307; RV32I-SW-NO-NEXT: # %bb.2: # %do_call2308; RV32I-SW-NO-NEXT: call foo309; RV32I-SW-NO-NEXT: .LBB3_3: # %exit310; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload311; RV32I-SW-NO-NEXT: lw s0, 8(sp) # 4-byte Folded Reload312; RV32I-SW-NO-NEXT: .cfi_restore ra313; RV32I-SW-NO-NEXT: .cfi_restore s0314; RV32I-SW-NO-NEXT: addi sp, sp, 16315; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 0316; RV32I-SW-NO-NEXT: ret317;318; RV32I-SW-LABEL: li_straightline_b:319; RV32I-SW: # %bb.0:320; RV32I-SW-NEXT: addi sp, sp, -16321; RV32I-SW-NEXT: .cfi_def_cfa_offset 16322; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill323; RV32I-SW-NEXT: sw s0, 8(sp) # 4-byte Folded Spill324; RV32I-SW-NEXT: .cfi_offset ra, -4325; RV32I-SW-NEXT: .cfi_offset s0, -8326; RV32I-SW-NEXT: mv s0, a1327; RV32I-SW-NEXT: li a1, 57328; RV32I-SW-NEXT: beq a0, a1, .LBB3_3329; RV32I-SW-NEXT: # %bb.1: # %do_call330; RV32I-SW-NEXT: call foo331; RV32I-SW-NEXT: li a0, 57332; RV32I-SW-NEXT: beq s0, a0, .LBB3_3333; RV32I-SW-NEXT: # %bb.2: # %do_call2334; RV32I-SW-NEXT: call foo335; RV32I-SW-NEXT: .LBB3_3: # %exit336; RV32I-SW-NEXT: lw ra, 12(sp) # 4-byte Folded Reload337; RV32I-SW-NEXT: lw s0, 8(sp) # 4-byte Folded Reload338; RV32I-SW-NEXT: .cfi_restore ra339; RV32I-SW-NEXT: .cfi_restore s0340; RV32I-SW-NEXT: addi sp, sp, 16341; RV32I-SW-NEXT: .cfi_def_cfa_offset 0342; RV32I-SW-NEXT: ret343;344; RV32I-SW-SR-LABEL: li_straightline_b:345; RV32I-SW-SR: # %bb.0:346; RV32I-SW-SR-NEXT: call t0, __riscv_save_1347; RV32I-SW-SR-NEXT: .cfi_def_cfa_offset 16348; RV32I-SW-SR-NEXT: .cfi_offset ra, -4349; RV32I-SW-SR-NEXT: .cfi_offset s0, -8350; RV32I-SW-SR-NEXT: mv s0, a1351; RV32I-SW-SR-NEXT: li a1, 57352; RV32I-SW-SR-NEXT: beq a0, a1, .LBB3_3353; RV32I-SW-SR-NEXT: # %bb.1: # %do_call354; RV32I-SW-SR-NEXT: call foo355; RV32I-SW-SR-NEXT: li a0, 57356; RV32I-SW-SR-NEXT: beq s0, a0, .LBB3_3357; RV32I-SW-SR-NEXT: # %bb.2: # %do_call2358; RV32I-SW-SR-NEXT: call foo359; RV32I-SW-SR-NEXT: .LBB3_3: # %exit360; RV32I-SW-SR-NEXT: tail __riscv_restore_1361;362; RV64I-SW-LABEL: li_straightline_b:363; RV64I-SW: # %bb.0:364; RV64I-SW-NEXT: addi sp, sp, -16365; RV64I-SW-NEXT: .cfi_def_cfa_offset 16366; RV64I-SW-NEXT: sd ra, 8(sp) # 8-byte Folded Spill367; RV64I-SW-NEXT: sd s0, 0(sp) # 8-byte Folded Spill368; RV64I-SW-NEXT: .cfi_offset ra, -8369; RV64I-SW-NEXT: .cfi_offset s0, -16370; RV64I-SW-NEXT: mv s0, a1371; RV64I-SW-NEXT: li a1, 57372; RV64I-SW-NEXT: beq a0, a1, .LBB3_3373; RV64I-SW-NEXT: # %bb.1: # %do_call374; RV64I-SW-NEXT: call foo375; RV64I-SW-NEXT: li a0, 57376; RV64I-SW-NEXT: beq s0, a0, .LBB3_3377; RV64I-SW-NEXT: # %bb.2: # %do_call2378; RV64I-SW-NEXT: call foo379; RV64I-SW-NEXT: .LBB3_3: # %exit380; RV64I-SW-NEXT: ld ra, 8(sp) # 8-byte Folded Reload381; RV64I-SW-NEXT: ld s0, 0(sp) # 8-byte Folded Reload382; RV64I-SW-NEXT: .cfi_restore ra383; RV64I-SW-NEXT: .cfi_restore s0384; RV64I-SW-NEXT: addi sp, sp, 16385; RV64I-SW-NEXT: .cfi_def_cfa_offset 0386; RV64I-SW-NEXT: ret387 %cmp0 = icmp eq i32 %a, 57388 br i1 %cmp0, label %exit, label %do_call389do_call:390 call i32 @foo()391 br label %next392next:393 %cmp1 = icmp eq i32 %b, 57394 br i1 %cmp1, label %exit, label %do_call2395do_call2:396 call i32 @foo()397 br label %exit398exit:399 ret void400}401 402; A further variant of "b" to show that we can shrink wrap this case403; if the second use of 57 is remat, and we eliminate the second live404; argument.405define void @li_straightline_c(i32 zeroext %a) {406; RV32I-SW-NO-LABEL: li_straightline_c:407; RV32I-SW-NO: # %bb.0:408; RV32I-SW-NO-NEXT: addi sp, sp, -16409; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 16410; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill411; RV32I-SW-NO-NEXT: .cfi_offset ra, -4412; RV32I-SW-NO-NEXT: li a1, 57413; RV32I-SW-NO-NEXT: beq a0, a1, .LBB4_3414; RV32I-SW-NO-NEXT: # %bb.1: # %do_call415; RV32I-SW-NO-NEXT: call foo416; RV32I-SW-NO-NEXT: li a1, 57417; RV32I-SW-NO-NEXT: beq a0, a1, .LBB4_3418; RV32I-SW-NO-NEXT: # %bb.2: # %do_call2419; RV32I-SW-NO-NEXT: call foo420; RV32I-SW-NO-NEXT: .LBB4_3: # %exit421; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload422; RV32I-SW-NO-NEXT: .cfi_restore ra423; RV32I-SW-NO-NEXT: addi sp, sp, 16424; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 0425; RV32I-SW-NO-NEXT: ret426;427; RV32I-SW-LABEL: li_straightline_c:428; RV32I-SW: # %bb.0:429; RV32I-SW-NEXT: li a1, 57430; RV32I-SW-NEXT: beq a0, a1, .LBB4_4431; RV32I-SW-NEXT: # %bb.1: # %do_call432; RV32I-SW-NEXT: addi sp, sp, -16433; RV32I-SW-NEXT: .cfi_def_cfa_offset 16434; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill435; RV32I-SW-NEXT: .cfi_offset ra, -4436; RV32I-SW-NEXT: call foo437; RV32I-SW-NEXT: li a1, 57438; RV32I-SW-NEXT: beq a0, a1, .LBB4_3439; RV32I-SW-NEXT: # %bb.2: # %do_call2440; RV32I-SW-NEXT: call foo441; RV32I-SW-NEXT: .LBB4_3:442; RV32I-SW-NEXT: lw ra, 12(sp) # 4-byte Folded Reload443; RV32I-SW-NEXT: .cfi_restore ra444; RV32I-SW-NEXT: addi sp, sp, 16445; RV32I-SW-NEXT: .cfi_def_cfa_offset 0446; RV32I-SW-NEXT: .LBB4_4: # %exit447; RV32I-SW-NEXT: ret448;449; RV32I-SW-SR-LABEL: li_straightline_c:450; RV32I-SW-SR: # %bb.0:451; RV32I-SW-SR-NEXT: li a1, 57452; RV32I-SW-SR-NEXT: beq a0, a1, .LBB4_4453; RV32I-SW-SR-NEXT: # %bb.1: # %do_call454; RV32I-SW-SR-NEXT: call t0, __riscv_save_0455; RV32I-SW-SR-NEXT: .cfi_def_cfa_offset 16456; RV32I-SW-SR-NEXT: .cfi_offset ra, -4457; RV32I-SW-SR-NEXT: call foo458; RV32I-SW-SR-NEXT: li a1, 57459; RV32I-SW-SR-NEXT: beq a0, a1, .LBB4_3460; RV32I-SW-SR-NEXT: # %bb.2: # %do_call2461; RV32I-SW-SR-NEXT: call foo462; RV32I-SW-SR-NEXT: .LBB4_3:463; RV32I-SW-SR-NEXT: tail __riscv_restore_0464; RV32I-SW-SR-NEXT: j .LBB4_4465; RV32I-SW-SR-NEXT: .LBB4_4: # %exit466; RV32I-SW-SR-NEXT: ret467;468; RV64I-SW-LABEL: li_straightline_c:469; RV64I-SW: # %bb.0:470; RV64I-SW-NEXT: li a1, 57471; RV64I-SW-NEXT: beq a0, a1, .LBB4_4472; RV64I-SW-NEXT: # %bb.1: # %do_call473; RV64I-SW-NEXT: addi sp, sp, -16474; RV64I-SW-NEXT: .cfi_def_cfa_offset 16475; RV64I-SW-NEXT: sd ra, 8(sp) # 8-byte Folded Spill476; RV64I-SW-NEXT: .cfi_offset ra, -8477; RV64I-SW-NEXT: call foo478; RV64I-SW-NEXT: li a1, 57479; RV64I-SW-NEXT: beq a0, a1, .LBB4_3480; RV64I-SW-NEXT: # %bb.2: # %do_call2481; RV64I-SW-NEXT: call foo482; RV64I-SW-NEXT: .LBB4_3:483; RV64I-SW-NEXT: ld ra, 8(sp) # 8-byte Folded Reload484; RV64I-SW-NEXT: .cfi_restore ra485; RV64I-SW-NEXT: addi sp, sp, 16486; RV64I-SW-NEXT: .cfi_def_cfa_offset 0487; RV64I-SW-NEXT: .LBB4_4: # %exit488; RV64I-SW-NEXT: ret489 %cmp0 = icmp eq i32 %a, 57490 br i1 %cmp0, label %exit, label %do_call491do_call:492 %b = call i32 @foo()493 br label %next494next:495 %cmp1 = icmp eq i32 %b, 57496 br i1 %cmp1, label %exit, label %do_call2497do_call2:498 call i32 @foo()499 br label %exit500exit:501 ret void502}503 504 505; In this case, the second use is in a loop, so using a callee506; saved register to avoid a remat is the profitable choice.507; FIXME: We can shrink wrap the frame setup around the loop508; and avoid it along the %bb.0 -> %exit edge509define void @li_loop(i32 zeroext %a, i32 zeroext %b) {510; RV32I-SW-NO-LABEL: li_loop:511; RV32I-SW-NO: # %bb.0:512; RV32I-SW-NO-NEXT: addi sp, sp, -16513; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 16514; RV32I-SW-NO-NEXT: sw ra, 12(sp) # 4-byte Folded Spill515; RV32I-SW-NO-NEXT: sw s0, 8(sp) # 4-byte Folded Spill516; RV32I-SW-NO-NEXT: sw s1, 4(sp) # 4-byte Folded Spill517; RV32I-SW-NO-NEXT: .cfi_offset ra, -4518; RV32I-SW-NO-NEXT: .cfi_offset s0, -8519; RV32I-SW-NO-NEXT: .cfi_offset s1, -12520; RV32I-SW-NO-NEXT: li s1, 57521; RV32I-SW-NO-NEXT: beq a0, s1, .LBB5_3522; RV32I-SW-NO-NEXT: # %bb.1: # %do_call.preheader523; RV32I-SW-NO-NEXT: mv s0, a1524; RV32I-SW-NO-NEXT: .LBB5_2: # %do_call525; RV32I-SW-NO-NEXT: # =>This Inner Loop Header: Depth=1526; RV32I-SW-NO-NEXT: call foo527; RV32I-SW-NO-NEXT: bne s0, s1, .LBB5_2528; RV32I-SW-NO-NEXT: .LBB5_3: # %exit529; RV32I-SW-NO-NEXT: lw ra, 12(sp) # 4-byte Folded Reload530; RV32I-SW-NO-NEXT: lw s0, 8(sp) # 4-byte Folded Reload531; RV32I-SW-NO-NEXT: lw s1, 4(sp) # 4-byte Folded Reload532; RV32I-SW-NO-NEXT: .cfi_restore ra533; RV32I-SW-NO-NEXT: .cfi_restore s0534; RV32I-SW-NO-NEXT: .cfi_restore s1535; RV32I-SW-NO-NEXT: addi sp, sp, 16536; RV32I-SW-NO-NEXT: .cfi_def_cfa_offset 0537; RV32I-SW-NO-NEXT: ret538;539; RV32I-SW-LABEL: li_loop:540; RV32I-SW: # %bb.0:541; RV32I-SW-NEXT: addi sp, sp, -16542; RV32I-SW-NEXT: .cfi_def_cfa_offset 16543; RV32I-SW-NEXT: sw ra, 12(sp) # 4-byte Folded Spill544; RV32I-SW-NEXT: sw s0, 8(sp) # 4-byte Folded Spill545; RV32I-SW-NEXT: sw s1, 4(sp) # 4-byte Folded Spill546; RV32I-SW-NEXT: .cfi_offset ra, -4547; RV32I-SW-NEXT: .cfi_offset s0, -8548; RV32I-SW-NEXT: .cfi_offset s1, -12549; RV32I-SW-NEXT: li s1, 57550; RV32I-SW-NEXT: beq a0, s1, .LBB5_3551; RV32I-SW-NEXT: # %bb.1: # %do_call.preheader552; RV32I-SW-NEXT: mv s0, a1553; RV32I-SW-NEXT: .LBB5_2: # %do_call554; RV32I-SW-NEXT: # =>This Inner Loop Header: Depth=1555; RV32I-SW-NEXT: call foo556; RV32I-SW-NEXT: bne s0, s1, .LBB5_2557; RV32I-SW-NEXT: .LBB5_3: # %exit558; RV32I-SW-NEXT: lw ra, 12(sp) # 4-byte Folded Reload559; RV32I-SW-NEXT: lw s0, 8(sp) # 4-byte Folded Reload560; RV32I-SW-NEXT: lw s1, 4(sp) # 4-byte Folded Reload561; RV32I-SW-NEXT: .cfi_restore ra562; RV32I-SW-NEXT: .cfi_restore s0563; RV32I-SW-NEXT: .cfi_restore s1564; RV32I-SW-NEXT: addi sp, sp, 16565; RV32I-SW-NEXT: .cfi_def_cfa_offset 0566; RV32I-SW-NEXT: ret567;568; RV32I-SW-SR-LABEL: li_loop:569; RV32I-SW-SR: # %bb.0:570; RV32I-SW-SR-NEXT: call t0, __riscv_save_2571; RV32I-SW-SR-NEXT: .cfi_def_cfa_offset 16572; RV32I-SW-SR-NEXT: .cfi_offset ra, -4573; RV32I-SW-SR-NEXT: .cfi_offset s0, -8574; RV32I-SW-SR-NEXT: .cfi_offset s1, -12575; RV32I-SW-SR-NEXT: li s1, 57576; RV32I-SW-SR-NEXT: beq a0, s1, .LBB5_3577; RV32I-SW-SR-NEXT: # %bb.1: # %do_call.preheader578; RV32I-SW-SR-NEXT: mv s0, a1579; RV32I-SW-SR-NEXT: .LBB5_2: # %do_call580; RV32I-SW-SR-NEXT: # =>This Inner Loop Header: Depth=1581; RV32I-SW-SR-NEXT: call foo582; RV32I-SW-SR-NEXT: bne s0, s1, .LBB5_2583; RV32I-SW-SR-NEXT: .LBB5_3: # %exit584; RV32I-SW-SR-NEXT: tail __riscv_restore_2585;586; RV64I-SW-LABEL: li_loop:587; RV64I-SW: # %bb.0:588; RV64I-SW-NEXT: addi sp, sp, -32589; RV64I-SW-NEXT: .cfi_def_cfa_offset 32590; RV64I-SW-NEXT: sd ra, 24(sp) # 8-byte Folded Spill591; RV64I-SW-NEXT: sd s0, 16(sp) # 8-byte Folded Spill592; RV64I-SW-NEXT: sd s1, 8(sp) # 8-byte Folded Spill593; RV64I-SW-NEXT: .cfi_offset ra, -8594; RV64I-SW-NEXT: .cfi_offset s0, -16595; RV64I-SW-NEXT: .cfi_offset s1, -24596; RV64I-SW-NEXT: li s1, 57597; RV64I-SW-NEXT: beq a0, s1, .LBB5_3598; RV64I-SW-NEXT: # %bb.1: # %do_call.preheader599; RV64I-SW-NEXT: mv s0, a1600; RV64I-SW-NEXT: .LBB5_2: # %do_call601; RV64I-SW-NEXT: # =>This Inner Loop Header: Depth=1602; RV64I-SW-NEXT: call foo603; RV64I-SW-NEXT: bne s0, s1, .LBB5_2604; RV64I-SW-NEXT: .LBB5_3: # %exit605; RV64I-SW-NEXT: ld ra, 24(sp) # 8-byte Folded Reload606; RV64I-SW-NEXT: ld s0, 16(sp) # 8-byte Folded Reload607; RV64I-SW-NEXT: ld s1, 8(sp) # 8-byte Folded Reload608; RV64I-SW-NEXT: .cfi_restore ra609; RV64I-SW-NEXT: .cfi_restore s0610; RV64I-SW-NEXT: .cfi_restore s1611; RV64I-SW-NEXT: addi sp, sp, 32612; RV64I-SW-NEXT: .cfi_def_cfa_offset 0613; RV64I-SW-NEXT: ret614 %cmp0 = icmp eq i32 %a, 57615 br i1 %cmp0, label %exit, label %do_call616do_call:617 call i32 @foo()618 %cmp1 = icmp eq i32 %b, 57619 br i1 %cmp1, label %exit, label %do_call620exit:621 ret void622}623 624declare zeroext i32 @foo()625