| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s |
| ; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s |
| |
| target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" |
| target triple = "x86_64-pc-linux-gnu" |
| |
| ; `unreachable` block has conditional predecessors, |
| ; but everything we'd sink from unconditional predecessors are speculatable. |
| ; Also, too many phi's would normally be needed. |
| define void @t0(i4 %cond, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { |
| ; CHECK-LABEL: @t0( |
| ; CHECK-NEXT: switch i4 [[COND:%.*]], label [[END:%.*]] [ |
| ; CHECK-NEXT: i4 0, label [[END_SINK_SPLIT:%.*]] |
| ; CHECK-NEXT: i4 -1, label [[END_SINK_SPLIT]] |
| ; CHECK-NEXT: i4 1, label [[BB1:%.*]] |
| ; CHECK-NEXT: i4 -2, label [[BB1]] |
| ; CHECK-NEXT: ] |
| ; CHECK: bb1: |
| ; CHECK-NEXT: br label [[END_SINK_SPLIT]] |
| ; CHECK: end.sink.split: |
| ; CHECK-NEXT: [[H_SINK:%.*]] = phi i32 [ [[H:%.*]], [[BB1]] ], [ [[E:%.*]], [[TMP0:%.*]] ], [ [[E]], [[TMP0]] ] |
| ; CHECK-NEXT: [[G_SINK:%.*]] = phi i32 [ [[G:%.*]], [[BB1]] ], [ [[D:%.*]], [[TMP0]] ], [ [[D]], [[TMP0]] ] |
| ; CHECK-NEXT: [[V4:%.*]] = add i32 [[A:%.*]], [[B:%.*]] |
| ; CHECK-NEXT: [[V5:%.*]] = add i32 [[V4]], [[C:%.*]] |
| ; CHECK-NEXT: [[V6:%.*]] = add i32 [[G_SINK]], [[H_SINK]] |
| ; CHECK-NEXT: [[R7:%.*]] = add i32 [[V5]], [[V6]] |
| ; CHECK-NEXT: call void @use32(i32 [[R7]]) |
| ; CHECK-NEXT: unreachable |
| ; CHECK: end: |
| ; CHECK-NEXT: unreachable |
| ; |
| switch i4 %cond, label %end [ |
| i4 0, label %bb0 |
| i4 -1, label %bb0 |
| i4 1, label %bb1 |
| i4 -2, label %bb1 |
| ] |
| |
| bb0: |
| %v0 = add i32 %a, %b |
| %v1 = add i32 %v0, %c |
| %v2 = add i32 %d, %e |
| %r3 = add i32 %v1, %v2 |
| call void @use32(i32 %r3) |
| br label %end |
| |
| bb1: |
| %v4 = add i32 %a, %b |
| %v5 = add i32 %v4, %c |
| %v6 = add i32 %g, %h |
| %r7 = add i32 %v5, %v6 |
| call void @use32(i32 %r7) |
| br label %end |
| |
| end: |
| unreachable |
| } |
| |
| ; Same, as @t0, but there's also a loop. |
| define void @t1(i4 %cond, i1 %cond.loop, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { |
| ; CHECK-LABEL: @t1( |
| ; CHECK-NEXT: switch i4 [[COND:%.*]], label [[END_EARLY:%.*]] [ |
| ; CHECK-NEXT: i4 0, label [[BB0:%.*]] |
| ; CHECK-NEXT: i4 -1, label [[BB0]] |
| ; CHECK-NEXT: i4 1, label [[BB1:%.*]] |
| ; CHECK-NEXT: i4 -2, label [[BB1]] |
| ; CHECK-NEXT: ] |
| ; CHECK: bb0: |
| ; CHECK-NEXT: [[V0:%.*]] = add i32 [[A:%.*]], [[B:%.*]] |
| ; CHECK-NEXT: [[V1:%.*]] = add i32 [[V0]], [[C:%.*]] |
| ; CHECK-NEXT: [[V2:%.*]] = add i32 [[D:%.*]], [[E:%.*]] |
| ; CHECK-NEXT: [[R3:%.*]] = add i32 [[V1]], [[V2]] |
| ; CHECK-NEXT: call void @use32(i32 [[R3]]) |
| ; CHECK-NEXT: br label [[END_EARLY]] |
| ; CHECK: bb1: |
| ; CHECK-NEXT: [[V4:%.*]] = add i32 [[A]], [[B]] |
| ; CHECK-NEXT: [[V5:%.*]] = add i32 [[V4]], [[C]] |
| ; CHECK-NEXT: [[V6:%.*]] = add i32 [[G:%.*]], [[H:%.*]] |
| ; CHECK-NEXT: [[R7:%.*]] = add i32 [[V5]], [[V6]] |
| ; CHECK-NEXT: call void @use32(i32 [[R7]]) |
| ; CHECK-NEXT: br label [[END_EARLY]] |
| ; CHECK: end.early: |
| ; CHECK-NEXT: call void @sideeffect() |
| ; CHECK-NEXT: br i1 [[COND_LOOP:%.*]], label [[END_EARLY]], label [[END:%.*]] |
| ; CHECK: end: |
| ; CHECK-NEXT: call void @sideeffect() |
| ; CHECK-NEXT: unreachable |
| ; |
| switch i4 %cond, label %end.early [ |
| i4 0, label %bb0 |
| i4 -1, label %bb0 |
| i4 1, label %bb1 |
| i4 -2, label %bb1 |
| ] |
| |
| bb0: |
| %v0 = add i32 %a, %b |
| %v1 = add i32 %v0, %c |
| %v2 = add i32 %d, %e |
| %r3 = add i32 %v1, %v2 |
| call void @use32(i32 %r3) |
| br label %end.early |
| |
| bb1: |
| %v4 = add i32 %a, %b |
| %v5 = add i32 %v4, %c |
| %v6 = add i32 %g, %h |
| %r7 = add i32 %v5, %v6 |
| call void @use32(i32 %r7) |
| br label %end.early |
| |
| end.early: |
| call void @sideeffect() |
| br i1 %cond.loop, label %end.early, label %end |
| |
| end: |
| call void @sideeffect() |
| unreachable |
| } |
| |
| declare void @use32(i32) speculatable |
| |
| declare void @sideeffect() |