232 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -passes=gvn-sink -S %s | FileCheck %s3 4declare i32 @foo()5 6define void @loop1() {7; CHECK-LABEL: define void @loop1() {8; CHECK-NEXT: entry:9; CHECK-NEXT: br label [[LOOP:%.*]]10; CHECK: loop:11; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()12; CHECK-NEXT: br label [[LOOP]]13;14entry:15 %c1 = call i32 @foo()16 br label %loop17 18loop:19 %c2 = call i32 @foo()20 br label %loop21}22 23define void @uncond_succ_no_loop() {24; CHECK-LABEL: define void @uncond_succ_no_loop() {25; CHECK-NEXT: entry:26; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()27; CHECK-NEXT: br label [[EXIT:%.*]]28; CHECK: exit:29; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()30; CHECK-NEXT: ret void31;32entry:33 %c1 = call i32 @foo()34 br label %exit35 36exit:37 %c2 = call i32 @foo()38 ret void39}40 41define void @loop_with_store(ptr %a) {42; CHECK-LABEL: define void @loop_with_store43; CHECK-SAME: (ptr [[A:%.*]]) {44; CHECK-NEXT: entry:45; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()46; CHECK-NEXT: br label [[LOOP:%.*]]47; CHECK: loop:48; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()49; CHECK-NEXT: store i32 0, ptr [[A]], align 450; CHECK-NEXT: br label [[LOOP]]51;52entry:53 %c1 = call i32 @foo()54 br label %loop55 56loop:57 %c2 = call i32 @foo()58 store i32 0, ptr %a59 br label %loop60}61 62define void @loop_linked_latches() {63; CHECK-LABEL: define void @loop_linked_latches() {64; CHECK-NEXT: entry:65; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()66; CHECK-NEXT: br label [[LOOP:%.*]]67; CHECK: loop:68; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()69; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[C2]], 10070; CHECK-NEXT: br i1 [[C]], label [[LATCH_1:%.*]], label [[EXIT:%.*]]71; CHECK: latch.1:72; CHECK-NEXT: br label [[LATCH_2:%.*]]73; CHECK: latch.2:74; CHECK-NEXT: br label [[LOOP]]75; CHECK: exit:76; CHECK-NEXT: ret void77;78entry:79 %c1 = call i32 @foo()80 br label %loop81 82loop:83 %c2 = call i32 @foo()84 %c = icmp eq i32 %c2, 10085 br i1 %c, label %latch.1, label %exit86 87latch.1:88 br label %latch.289 90latch.2:91 br label %loop92 93 94exit:95 ret void96}97 98define void @loop_with_branch(i32 %s) {99; CHECK-LABEL: define void @loop_with_branch100; CHECK-SAME: (i32 [[S:%.*]]) {101; CHECK-NEXT: entry:102; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]103; CHECK: loop.header:104; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()105; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 100106; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]107; CHECK: loop.latch:108; CHECK-NEXT: br label [[LOOP_HEADER]]109; CHECK: exit:110; CHECK-NEXT: ret void111;112entry:113 %c1 = call i32 @foo()114 br label %loop.header115 116loop.header:117 %cmp = icmp eq i32 %s, 100118 br i1 %cmp, label %loop.latch, label %exit119 120loop.latch:121 %c2 = call i32 @foo()122 br label %loop.header123 124exit:125 ret void126}127 128define void @loop_with_switch(i32 %s) {129; CHECK-LABEL: define void @loop_with_switch130; CHECK-SAME: (i32 [[S:%.*]]) {131; CHECK-NEXT: entry:132; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]133; CHECK: loop.header:134; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()135; CHECK-NEXT: switch i32 [[S]], label [[LOOP_LATCH:%.*]] [136; CHECK-NEXT: i32 0, label [[EXIT:%.*]]137; CHECK-NEXT: ]138; CHECK: loop.latch:139; CHECK-NEXT: br label [[LOOP_HEADER]]140; CHECK: exit:141; CHECK-NEXT: ret void142;143entry:144 %c1 = call i32 @foo()145 br label %loop.header146 147loop.header:148 switch i32 %s, label %loop.latch [149 i32 0, label %exit150 ]151 152loop.latch:153 %c2 = call i32 @foo()154 br label %loop.header155 156exit:157 ret void158}159 160define void @cycle_latch_not_dominated_by_header_branch(i1 %c, i32 %s) {161; CHECK-LABEL: define void @cycle_latch_not_dominated_by_header_branch162; CHECK-SAME: (i1 [[C:%.*]], i32 [[S:%.*]]) {163; CHECK-NEXT: entry:164; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]165; CHECK: then:166; CHECK-NEXT: br label [[CYCLE_1:%.*]]167; CHECK: cycle.1:168; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()169; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 100170; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[CYCLE_2]]171; CHECK: cycle.2:172; CHECK-NEXT: br label [[CYCLE_1]]173; CHECK: exit:174; CHECK-NEXT: ret void175;176entry:177 br i1 %c, label %then, label %cycle.2178 179then:180 %c1 = call i32 @foo()181 br label %cycle.1182 183cycle.1:184 %cmp = icmp eq i32 %s, 100185 br i1 %cmp, label %exit, label %cycle.2186 187cycle.2:188 %c2 = call i32 @foo()189 br label %cycle.1190 191exit:192 ret void193}194 195define void @cycle_latch_not_dominated_by_header_switch(i1 %c, i32 %s) {196; CHECK-LABEL: define void @cycle_latch_not_dominated_by_header_switch197; CHECK-SAME: (i1 [[C:%.*]], i32 [[S:%.*]]) {198; CHECK-NEXT: entry:199; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]200; CHECK: then:201; CHECK-NEXT: br label [[CYCLE_1:%.*]]202; CHECK: cycle.1:203; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()204; CHECK-NEXT: switch i32 [[S]], label [[EXIT:%.*]] [205; CHECK-NEXT: i32 0, label [[CYCLE_2]]206; CHECK-NEXT: ]207; CHECK: cycle.2:208; CHECK-NEXT: br label [[CYCLE_1]]209; CHECK: exit:210; CHECK-NEXT: ret void211;212entry:213 br i1 %c, label %then, label %cycle.2214 215then:216 %c1 = call i32 @foo()217 br label %cycle.1218 219cycle.1:220 switch i32 %s, label %exit [221 i32 0, label %cycle.2222 ]223 224cycle.2:225 %c2 = call i32 @foo()226 br label %cycle.1227 228exit:229 ret void230}231 232