blob: 0950a97f57d23225ca6b6810c3a8197e352b0c58 [file]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
; RUN: opt < %s -indirectbr-expand -S | FileCheck %s
; RUN: opt < %s -passes=indirectbr-expand -S | FileCheck %s
;
; REQUIRES: x86-registered-target
target triple = "x86_64-unknown-linux-gnu"
@test1.targets = constant [4 x ptr] [ptr blockaddress(@test1, %bb0),
ptr blockaddress(@test1, %bb1),
ptr blockaddress(@test1, %bb2),
ptr blockaddress(@test1, %bb3)]
;.
; CHECK: @test1.targets = constant [4 x ptr] [ptr inttoptr (i64 1 to ptr), ptr inttoptr (i64 2 to ptr), ptr inttoptr (i64 3 to ptr), ptr blockaddress(@test1, %bb3)]
;.
define void @test1(ptr readonly %p, ptr %sink) #0 {
; CHECK-LABEL: define void @test1(
; CHECK-SAME: ptr readonly [[P:%.*]], ptr [[SINK:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[I0:%.*]] = load i64, ptr [[P]], align 8
; CHECK-NEXT: [[TARGET_I0:%.*]] = getelementptr [4 x ptr], ptr @test1.targets, i64 0, i64 [[I0]]
; CHECK-NEXT: [[TARGET0:%.*]] = load ptr, ptr [[TARGET_I0]], align 8
; CHECK-NEXT: [[TARGET0_SWITCH_CAST:%.*]] = ptrtoint ptr [[TARGET0]] to i64
; CHECK-NEXT: br label %[[SWITCH_BB:.*]]
; CHECK: [[BB0:.*]]:
; CHECK-NEXT: store volatile i64 0, ptr [[SINK]], align 8
; CHECK-NEXT: br label %[[LATCH:.*]]
; CHECK: [[BB1:.*]]:
; CHECK-NEXT: store volatile i64 1, ptr [[SINK]], align 8
; CHECK-NEXT: br label %[[LATCH]]
; CHECK: [[BB2:.*]]:
; CHECK-NEXT: store volatile i64 2, ptr [[SINK]], align 8
; CHECK-NEXT: br label %[[LATCH]]
; CHECK: [[BB3:.*:]]
; CHECK-NEXT: store volatile i64 3, ptr [[SINK]], align 8
; CHECK-NEXT: br label %[[LATCH]]
; CHECK: [[LATCH]]:
; CHECK-NEXT: [[I_NEXT:%.*]] = load i64, ptr [[P]], align 8
; CHECK-NEXT: [[TARGET_I_NEXT:%.*]] = getelementptr [4 x ptr], ptr @test1.targets, i64 0, i64 [[I_NEXT]]
; CHECK-NEXT: [[TARGET_NEXT:%.*]] = load ptr, ptr [[TARGET_I_NEXT]], align 8
; CHECK-NEXT: [[TARGET_NEXT_SWITCH_CAST:%.*]] = ptrtoint ptr [[TARGET_NEXT]] to i64
; CHECK-NEXT: br label %[[SWITCH_BB]]
; CHECK: [[SWITCH_BB]]:
; CHECK-NEXT: [[SWITCH_VALUE_PHI:%.*]] = phi i64 [ [[TARGET0_SWITCH_CAST]], %[[ENTRY]] ], [ [[TARGET_NEXT_SWITCH_CAST]], %[[LATCH]] ]
; CHECK-NEXT: switch i64 [[SWITCH_VALUE_PHI]], label %[[BB0]] [
; CHECK-NEXT: i64 2, label %[[BB1]]
; CHECK-NEXT: i64 3, label %[[BB2]]
; CHECK-NEXT: ]
;
entry:
%i0 = load i64, ptr %p
%target.i0 = getelementptr [4 x ptr], ptr @test1.targets, i64 0, i64 %i0
%target0 = load ptr, ptr %target.i0
; Only a subset of blocks are viable successors here.
indirectbr ptr %target0, [label %bb0, label %bb1]
bb0:
store volatile i64 0, ptr %sink
br label %latch
bb1:
store volatile i64 1, ptr %sink
br label %latch
bb2:
store volatile i64 2, ptr %sink
br label %latch
bb3:
store volatile i64 3, ptr %sink
br label %latch
latch:
%i.next = load i64, ptr %p
%target.i.next = getelementptr [4 x ptr], ptr @test1.targets, i64 0, i64 %i.next
%target.next = load ptr, ptr %target.i.next
; A different subset of blocks are viable successors here.
indirectbr ptr %target.next, [label %bb1, label %bb2]
}
attributes #0 = { "target-features"="+retpoline" }
;.
; CHECK: attributes #[[ATTR0]] = { "target-features"="+retpoline" }
;.