196 lines · plain
1; RUN: opt < %s -S -passes=speculative-execution \2; RUN: -spec-exec-max-speculation-cost 4 -spec-exec-max-not-hoisted 3 \3; RUN: | FileCheck %s4 5target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"6 7; Hoist in if-then pattern.8define void @ifThen() {9; CHECK-LABEL: @ifThen(10; CHECK: %x = add i32 2, 311; CHECK: br i1 true12 br i1 true, label %a, label %b13; CHECK: a:14a:15 %x = add i32 2, 316; CHECK: br label17 br label %b18; CHECK: b:19b:20; CHECK: ret void21 ret void22}23 24; Hoist in if-else pattern.25define void @ifElse() {26; CHECK-LABEL: @ifElse(27; CHECK: %x = add i32 2, 328; CHECK: br i1 true29 br i1 true, label %b, label %a30; CHECK: a:31a:32 %x = add i32 2, 333; CHECK: br label34 br label %b35; CHECK: b:36b:37; CHECK: ret void38 ret void39}40 41; Hoist in if-then-else pattern if it is equivalent to if-then.42define void @ifElseThenAsIfThen() {43; CHECK-LABEL: @ifElseThenAsIfThen(44; CHECK: %x = add i32 2, 345; CHECK: br46 br i1 true, label %a, label %b47; CHECK: a:48a:49 %x = add i32 2, 350; CHECK: br label51 br label %c52; CHECK: b:53b:54 br label %c55; CHECK: c56c:57 ret void58}59 60; Hoist in if-then-else pattern if it is equivalent to if-else.61define void @ifElseThenAsIfElse() {62; CHECK-LABEL: @ifElseThenAsIfElse(63; CHECK: %x = add i32 2, 364; CHECK: br65 br i1 true, label %b, label %a66; CHECK: a:67a:68 %x = add i32 2, 369; CHECK: br label70 br label %c71; CHECK: b:72b:73 br label %c74; CHECK: c75c:76 ret void77}78 79; Do not hoist if-then-else pattern if it is not equivalent to if-then80; or if-else.81define void @ifElseThen() {82; CHECK-LABEL: @ifElseThen(83; CHECK: br84 br i1 true, label %a, label %b85; CHECK: a:86a:87; CHECK: %x = add88 %x = add i32 2, 389; CHECK: br label90 br label %c91; CHECK: b:92b:93; CHECK: %y = add94 %y = add i32 2, 395 br label %c96; CHECK: c97c:98 ret void99}100 101; Do not hoist loads and do not hoist an instruction past a definition of102; an operand.103define void @doNotHoistPastDef() {104; CHECK-LABEL: @doNotHoistPastDef(105 br i1 true, label %b, label %a106; CHECK-NOT: load107; CHECK-NOT: add108; CHECK: a:109a:110; CHECK: %def = load111 %def = load i32, ptr null112; CHECK: %use = add113 %use = add i32 %def, 0114 br label %b115; CHECK: b:116b:117 ret void118}119 120; Case with nothing to speculate.121define void @nothingToSpeculate() {122; CHECK-LABEL: @nothingToSpeculate(123 br i1 true, label %b, label %a124; CHECK: a:125a:126; CHECK: %def = load127 %def = load i32, ptr null128 br label %b129; CHECK: b:130b:131 ret void132}133 134; Still hoist if an operand is defined before the block or is itself hoisted.135define void @hoistIfNotPastDef() {136; CHECK-LABEL: @hoistIfNotPastDef(137; CHECK: %x = load138 %x = load i32, ptr null139; CHECK: %y = add i32 %x, 1140; CHECK: %z = add i32 %y, 1141; CHECK: br142 br i1 true, label %b, label %a143; CHECK: a:144a:145 %y = add i32 %x, 1146 %z = add i32 %y, 1147 br label %b148; CHECK: b:149b:150 ret void151}152 153; Do not hoist if the speculation cost is too high.154define void @costTooHigh() {155; CHECK-LABEL: @costTooHigh(156; CHECK: br157 br i1 true, label %b, label %a158; CHECK: a:159a:160; CHECK: %r1 = add161 %r1 = add i32 1, 1162; CHECK: %r2 = add163 %r2 = add i32 1, 1164; CHECK: %r3 = add165 %r3 = add i32 1, 1166; CHECK: %r4 = add167 %r4 = add i32 1, 1168; CHECK: %r5 = add169 %r5 = add i32 1, 1170 br label %b171; CHECK: b:172b:173 ret void174}175 176; Do not hoist if too many instructions are left behind.177define void @tooMuchLeftBehind() {178; CHECK-LABEL: @tooMuchLeftBehind(179; CHECK: br180 br i1 true, label %b, label %a181; CHECK: a:182a:183; CHECK: %x = load184 %x = load i32, ptr null185; CHECK: %r1 = add186 %r1 = add i32 %x, 1187; CHECK: %r2 = add188 %r2 = add i32 %x, 1189; CHECK: %r3 = add190 %r3 = add i32 %x, 1191 br label %b192; CHECK: b:193b:194 ret void195}196