370 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -mtriple=riscv64 < %s | FileCheck %s3 4define i1 @sink_li(ptr %text, ptr %text.addr.0) nounwind {5; CHECK-LABEL: sink_li:6; CHECK: # %bb.0: # %entry7; CHECK-NEXT: addi sp, sp, -328; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill9; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill10; CHECK-NEXT: sd s1, 8(sp) # 8-byte Folded Spill11; CHECK-NEXT: sd s2, 0(sp) # 8-byte Folded Spill12; CHECK-NEXT: mv s1, a113; CHECK-NEXT: mv s0, a014; CHECK-NEXT: call toupper15; CHECK-NEXT: li a1, 016; CHECK-NEXT: beqz s0, .LBB0_2517; CHECK-NEXT: .LBB0_1: # %while.body18; CHECK-NEXT: # =>This Inner Loop Header: Depth=119; CHECK-NEXT: j .LBB0_320; CHECK-NEXT: # %bb.2: # %while.body21; CHECK-NEXT: j .LBB0_1522; CHECK-NEXT: .LBB0_3: # %while.body.123; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=124; CHECK-NEXT: j .LBB0_525; CHECK-NEXT: # %bb.4: # %while.body.126; CHECK-NEXT: j .LBB0_1627; CHECK-NEXT: .LBB0_5: # %while.body.328; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=129; CHECK-NEXT: j .LBB0_730; CHECK-NEXT: # %bb.6: # %while.body.331; CHECK-NEXT: j .LBB0_1832; CHECK-NEXT: .LBB0_7: # %while.body.433; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=134; CHECK-NEXT: j .LBB0_935; CHECK-NEXT: # %bb.8: # %while.body.436; CHECK-NEXT: j .LBB0_2037; CHECK-NEXT: .LBB0_9: # %while.body.538; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=139; CHECK-NEXT: j .LBB0_1140; CHECK-NEXT: # %bb.10: # %while.body.541; CHECK-NEXT: j .LBB0_2242; CHECK-NEXT: .LBB0_11: # %while.body.643; CHECK-NEXT: # in Loop: Header=BB0_1 Depth=144; CHECK-NEXT: j .LBB0_145; CHECK-NEXT: # %bb.12: # %while.body.646; CHECK-NEXT: # %bb.13: # %while.body.647; CHECK-NEXT: # %bb.14: # %strdup.exit.split.loop.exit12648; CHECK-NEXT: addi s0, s1, 749; CHECK-NEXT: j .LBB0_2450; CHECK-NEXT: .LBB0_15: # %while.body51; CHECK-NEXT: j .LBB0_1752; CHECK-NEXT: .LBB0_16: # %while.body.153; CHECK-NEXT: .LBB0_17: # %strdup.exit.loopexit54; CHECK-NEXT: li s0, 055; CHECK-NEXT: j .LBB0_2456; CHECK-NEXT: .LBB0_18: # %while.body.357; CHECK-NEXT: # %bb.19: # %strdup.exit.split.loop.exit12058; CHECK-NEXT: addi s0, s1, 459; CHECK-NEXT: j .LBB0_2460; CHECK-NEXT: .LBB0_20: # %while.body.461; CHECK-NEXT: # %bb.21: # %strdup.exit.split.loop.exit12262; CHECK-NEXT: addi s0, s1, 563; CHECK-NEXT: j .LBB0_2464; CHECK-NEXT: .LBB0_22: # %while.body.565; CHECK-NEXT: j .LBB0_2466; CHECK-NEXT: # %bb.23:67; CHECK-NEXT: li a1, 068; CHECK-NEXT: j .LBB0_2569; CHECK-NEXT: .LBB0_24: # %strdup.exit70; CHECK-NEXT: li s1, 071; CHECK-NEXT: mv s2, a072; CHECK-NEXT: li a0, 073; CHECK-NEXT: mv a1, s074; CHECK-NEXT: jalr s175; CHECK-NEXT: li a0, 076; CHECK-NEXT: mv a1, s277; CHECK-NEXT: li a2, 078; CHECK-NEXT: jalr s179; CHECK-NEXT: li a1, 180; CHECK-NEXT: .LBB0_25: # %return81; CHECK-NEXT: mv a0, a182; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload83; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload84; CHECK-NEXT: ld s1, 8(sp) # 8-byte Folded Reload85; CHECK-NEXT: ld s2, 0(sp) # 8-byte Folded Reload86; CHECK-NEXT: addi sp, sp, 3287; CHECK-NEXT: ret88entry:89 %call = call i32 @toupper()90 %tobool.not = icmp eq ptr %text, null91 br i1 %tobool.not, label %return, label %while.body92 93while.body: ; preds = %while.body.6, %while.body.6, %entry94 switch i8 1, label %strdup.exit.split.loop.exit114 [95 i8 1, label %while.body.196 i8 9, label %while.body.197 i8 0, label %return98 ]99 100while.body.1: ; preds = %while.body, %while.body101 switch i8 1, label %strdup.exit [102 i8 1, label %while.body.3103 i8 9, label %while.body.3104 i8 0, label %return105 ]106 107while.body.3: ; preds = %while.body.1, %while.body.1108 switch i8 1, label %strdup.exit.split.loop.exit120 [109 i8 32, label %while.body.4110 i8 1, label %while.body.4111 i8 0, label %return112 ]113 114while.body.4: ; preds = %while.body.3, %while.body.3115 switch i8 1, label %strdup.exit.split.loop.exit122 [116 i8 32, label %while.body.5117 i8 1, label %while.body.5118 i8 0, label %return119 ]120 121while.body.5: ; preds = %while.body.4, %while.body.4122 switch i8 1, label %strdup.exit.split.loop.exit124 [123 i8 1, label %while.body.6124 i8 9, label %while.body.6125 i8 0, label %return126 ]127 128while.body.6: ; preds = %while.body.5, %while.body.5129 switch i8 1, label %strdup.exit.split.loop.exit126 [130 i8 1, label %while.body131 i8 9, label %while.body132 i8 0, label %return133 ]134 135strdup.exit.split.loop.exit114: ; preds = %while.body136 br label %strdup.exit137 138strdup.exit.split.loop.exit120: ; preds = %while.body.3139 %incdec.ptr.3.le = getelementptr i8, ptr %text.addr.0, i64 4140 br label %strdup.exit141 142strdup.exit.split.loop.exit122: ; preds = %while.body.4143 %incdec.ptr.4.le = getelementptr i8, ptr %text.addr.0, i64 5144 br label %strdup.exit145 146strdup.exit.split.loop.exit124: ; preds = %while.body.5147 br label %strdup.exit148 149strdup.exit.split.loop.exit126: ; preds = %while.body.6150 %incdec.ptr.6.le = getelementptr i8, ptr %text.addr.0, i64 7151 br label %strdup.exit152 153strdup.exit: ; preds = %strdup.exit.split.loop.exit126, %strdup.exit.split.loop.exit124, %strdup.exit.split.loop.exit122, %strdup.exit.split.loop.exit120, %strdup.exit.split.loop.exit114, %while.body.1154 %text.addr.0.lcssa = phi ptr [ null, %strdup.exit.split.loop.exit114 ], [ %incdec.ptr.3.le, %strdup.exit.split.loop.exit120 ], [ %incdec.ptr.4.le, %strdup.exit.split.loop.exit122 ], [ %text, %strdup.exit.split.loop.exit124 ], [ %incdec.ptr.6.le, %strdup.exit.split.loop.exit126 ], [ null, %while.body.1 ]155 %call5.i = tail call ptr null(ptr null, ptr %text.addr.0.lcssa)156 %memchr64 = tail call ptr null(ptr null, i32 %call, i64 0)157 br label %return158 159return: ; preds = %strdup.exit, %while.body.6, %while.body.5, %while.body.4, %while.body.3, %while.body.1, %while.body, %entry160 %retval.1 = phi i1 [ false, %entry ], [ true, %strdup.exit ], [ false, %while.body ], [ false, %while.body.1 ], [ false, %while.body.3 ], [ false, %while.body.4 ], [ false, %while.body.5 ], [ false, %while.body.6 ]161 ret i1 %retval.1162}163 164declare i32 @toupper()165 166; In this example, %arg and the return value (13) have overlapping live167; intervals because the ABI mandidates they both be placed in a0.168define signext i32 @overlap_live_ranges(ptr %arg, i32 signext %arg1) {169; CHECK-LABEL: overlap_live_ranges:170; CHECK: # %bb.0: # %bb171; CHECK-NEXT: li a2, 1172; CHECK-NEXT: bne a1, a2, .LBB1_2173; CHECK-NEXT: # %bb.1: # %bb2174; CHECK-NEXT: lw a0, 4(a0)175; CHECK-NEXT: ret176; CHECK-NEXT: .LBB1_2:177; CHECK-NEXT: li a0, 13178; CHECK-NEXT: ret179bb:180 %i = icmp eq i32 %arg1, 1181 br i1 %i, label %bb2, label %bb5182 183bb2: ; preds = %bb184 %i3 = getelementptr inbounds nuw i8, ptr %arg, i64 4185 %i4 = load i32, ptr %i3, align 4186 br label %bb5187 188bb5: ; preds = %bb2, %bb189 %i6 = phi i32 [ %i4, %bb2 ], [ 13, %bb ]190 ret i32 %i6191}192 193 194; For switches, the values feeding the phi are always sunk into the195; target blocks as the IR syntax requires the intermediate block and196; DAG lowers it in the immediate predecessor of the phi.197define signext i32 @switch_dispatch(i8 %a) {198; CHECK-LABEL: switch_dispatch:199; CHECK: # %bb.0: # %bb200; CHECK-NEXT: addi sp, sp, -16201; CHECK-NEXT: .cfi_def_cfa_offset 16202; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill203; CHECK-NEXT: sd s0, 0(sp) # 8-byte Folded Spill204; CHECK-NEXT: .cfi_offset ra, -8205; CHECK-NEXT: .cfi_offset s0, -16206; CHECK-NEXT: zext.b a0, a0207; CHECK-NEXT: li a1, 31208; CHECK-NEXT: blt a1, a0, .LBB2_5209; CHECK-NEXT: # %bb.1: # %bb210; CHECK-NEXT: beqz a0, .LBB2_10211; CHECK-NEXT: # %bb.2: # %bb212; CHECK-NEXT: li a1, 12213; CHECK-NEXT: beq a0, a1, .LBB2_11214; CHECK-NEXT: # %bb.3: # %bb215; CHECK-NEXT: li a1, 13216; CHECK-NEXT: bne a0, a1, .LBB2_9217; CHECK-NEXT: # %bb.4: # %case.4218; CHECK-NEXT: li s0, 644219; CHECK-NEXT: j .LBB2_13220; CHECK-NEXT: .LBB2_5: # %bb221; CHECK-NEXT: li a1, 234222; CHECK-NEXT: beq a0, a1, .LBB2_9223; CHECK-NEXT: # %bb.6: # %bb224; CHECK-NEXT: li a1, 70225; CHECK-NEXT: beq a0, a1, .LBB2_12226; CHECK-NEXT: # %bb.7: # %bb227; CHECK-NEXT: li a1, 32228; CHECK-NEXT: bne a0, a1, .LBB2_9229; CHECK-NEXT: # %bb.8: # %case.0230; CHECK-NEXT: li s0, 13231; CHECK-NEXT: j .LBB2_13232; CHECK-NEXT: .LBB2_9: # %case.default233; CHECK-NEXT: li s0, 23234; CHECK-NEXT: j .LBB2_13235; CHECK-NEXT: .LBB2_10: # %case.5236; CHECK-NEXT: li s0, 54237; CHECK-NEXT: j .LBB2_13238; CHECK-NEXT: .LBB2_11: # %case.1239; CHECK-NEXT: li s0, 53240; CHECK-NEXT: j .LBB2_13241; CHECK-NEXT: .LBB2_12: # %case.2242; CHECK-NEXT: li s0, 33243; CHECK-NEXT: .LBB2_13: # %merge244; CHECK-NEXT: mv a0, s0245; CHECK-NEXT: call use246; CHECK-NEXT: mv a0, s0247; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload248; CHECK-NEXT: ld s0, 0(sp) # 8-byte Folded Reload249; CHECK-NEXT: .cfi_restore ra250; CHECK-NEXT: .cfi_restore s0251; CHECK-NEXT: addi sp, sp, 16252; CHECK-NEXT: .cfi_def_cfa_offset 0253; CHECK-NEXT: ret254bb:255 switch i8 %a, label %case.default [256 i8 32, label %case.0257 i8 12, label %case.1258 i8 70, label %case.2259 i8 -22, label %case.3260 i8 13, label %case.4261 i8 0, label %case.5262 ]263 264case.0:265 br label %merge266case.1:267 br label %merge268case.2:269 br label %merge270case.3:271 br label %merge272case.4:273 br label %merge274case.5:275 br label %merge276case.default:277 br label %merge278 279merge:280 %res = phi i32 [ 23, %case.default ], [ 13, %case.0 ], [ 53, %case.1 ], [ 33, %case.2 ], [ 23, %case.3 ], [ 644, %case.4 ], [ 54, %case.5 ]281 call void @use(i32 %res)282 ret i32 %res283}284 285; Same as for the switch, but written via manual branching.286define signext i32 @branch_dispatch(i8 %a) {287; CHECK-LABEL: branch_dispatch:288; CHECK: # %bb.0: # %case.0289; CHECK-NEXT: addi sp, sp, -16290; CHECK-NEXT: .cfi_def_cfa_offset 16291; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill292; CHECK-NEXT: sd s0, 0(sp) # 8-byte Folded Spill293; CHECK-NEXT: .cfi_offset ra, -8294; CHECK-NEXT: .cfi_offset s0, -16295; CHECK-NEXT: .cfi_remember_state296; CHECK-NEXT: zext.b a0, a0297; CHECK-NEXT: li a1, 32298; CHECK-NEXT: beq a0, a1, .LBB3_7299; CHECK-NEXT: # %bb.1: # %case.1300; CHECK-NEXT: li a1, 12301; CHECK-NEXT: beq a0, a1, .LBB3_8302; CHECK-NEXT: # %bb.2: # %case.2303; CHECK-NEXT: li a1, 70304; CHECK-NEXT: beq a0, a1, .LBB3_9305; CHECK-NEXT: # %bb.3: # %case.3306; CHECK-NEXT: li a1, 234307; CHECK-NEXT: li s0, 23308; CHECK-NEXT: beq a0, a1, .LBB3_10309; CHECK-NEXT: # %bb.4: # %case.4310; CHECK-NEXT: beqz a0, .LBB3_11311; CHECK-NEXT: # %bb.5: # %case.5312; CHECK-NEXT: li a1, 5313; CHECK-NEXT: bne a0, a1, .LBB3_10314; CHECK-NEXT: # %bb.6:315; CHECK-NEXT: li s0, 54316; CHECK-NEXT: j .LBB3_10317; CHECK-NEXT: .LBB3_7:318; CHECK-NEXT: li s0, 13319; CHECK-NEXT: j .LBB3_10320; CHECK-NEXT: .LBB3_8:321; CHECK-NEXT: li s0, 53322; CHECK-NEXT: j .LBB3_10323; CHECK-NEXT: .LBB3_9:324; CHECK-NEXT: li s0, 33325; CHECK-NEXT: .LBB3_10: # %merge326; CHECK-NEXT: mv a0, s0327; CHECK-NEXT: call use328; CHECK-NEXT: mv a0, s0329; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload330; CHECK-NEXT: ld s0, 0(sp) # 8-byte Folded Reload331; CHECK-NEXT: .cfi_restore ra332; CHECK-NEXT: .cfi_restore s0333; CHECK-NEXT: addi sp, sp, 16334; CHECK-NEXT: .cfi_def_cfa_offset 0335; CHECK-NEXT: ret336; CHECK-NEXT: .LBB3_11:337; CHECK-NEXT: .cfi_restore_state338; CHECK-NEXT: li s0, 644339; CHECK-NEXT: j .LBB3_10340case.0:341 %c0 = icmp ne i8 %a, 32342 br i1 %c0, label %case.1, label %merge343case.1:344 %c1 = icmp ne i8 %a, 12345 br i1 %c1, label %case.2, label %merge346case.2:347 %c2 = icmp ne i8 %a, 70348 br i1 %c2, label %case.3, label %merge349case.3:350 %c3 = icmp ne i8 %a, -22351 br i1 %c3, label %case.4, label %merge352case.4:353 %c4 = icmp ne i8 %a, 0354 br i1 %c4, label %case.5, label %merge355case.5:356 %c5 = icmp ne i8 %a, 5357 br i1 %c5, label %case.default, label %merge358case.default:359 br label %merge360 361merge:362 %res = phi i32 [ 23, %case.default ], [ 13, %case.0 ], [ 53, %case.1 ], [ 33, %case.2 ], [ 23, %case.3 ], [ 644, %case.4 ], [ 54, %case.5 ]363 call void @use(i32 %res)364 ret i32 %res365}366 367 368declare void @use(i32)369 370