blob: 5abb03a00f3da712bc598bdbff800e5bbb9130b7 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=jump-table-to-switch -S | FileCheck %s
@table1 = constant [4 x ptr] [ptr null, ptr @f0, ptr poison, ptr @f1]
@table2 = constant [3 x ptr] [ptr null, ptr poison, ptr null]
@table3 = constant [3 x ptr] [ptr null, ptr @f0, ptr null]
@table4 = constant [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @g0, ptr addrspace(1) null]
define i32 @f0() {
; CHECK-LABEL: define i32 @f0() {
; CHECK-NEXT: ret i32 10
;
ret i32 10
}
define i32 @f1() {
; CHECK-LABEL: define i32 @f1() {
; CHECK-NEXT: ret i32 11
;
ret i32 11
}
define i32 @g0() addrspace(1) {
; CHECK-LABEL: define i32 @g0() addrspace(1) {
; CHECK-NEXT: ret i32 20
;
ret i32 20
}
define i32 @test_holes(i64 %i) {
; CHECK-LABEL: define i32 @test_holes(
; CHECK-SAME: i64 [[I:%.*]]) {
; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds [4 x ptr], ptr @table1, i64 0, i64 [[I]]
; CHECK-NEXT: [[F:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: switch i64 [[I]], label %[[DEFAULT_SWITCH_CASE_UNREACHABLE:.*]] [
; CHECK-NEXT: i64 1, label %[[CALL_1:.*]]
; CHECK-NEXT: i64 3, label %[[CALL_3:.*]]
; CHECK-NEXT: ], !prof [[PROF0:![0-9]+]]
; CHECK: [[DEFAULT_SWITCH_CASE_UNREACHABLE]]:
; CHECK-NEXT: unreachable
; CHECK: [[CALL_1]]:
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f0()
; CHECK-NEXT: br label %[[DOTTAIL:.*]]
; CHECK: [[CALL_3]]:
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @f1()
; CHECK-NEXT: br label %[[DOTTAIL]]
; CHECK: [[DOTTAIL]]:
; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP1]], %[[CALL_1]] ], [ [[TMP2]], %[[CALL_3]] ]
; CHECK-NEXT: ret i32 [[TMP3]]
;
%p = getelementptr inbounds [4 x ptr], ptr @table1, i64 0, i64 %i
%f = load ptr, ptr %p, align 8
%r = call i32 %f()
ret i32 %r
}
define i32 @test_all_ubs(i64 %i) {
; CHECK-LABEL: define i32 @test_all_ubs(
; CHECK-SAME: i64 [[I:%.*]]) {
; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds [3 x ptr], ptr @table2, i64 0, i64 [[I]]
; CHECK-NEXT: [[F:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[R:%.*]] = call i32 [[F]]()
; CHECK-NEXT: ret i32 [[R]]
;
%p = getelementptr inbounds [3 x ptr], ptr @table2, i64 0, i64 %i
%f = load ptr, ptr %p, align 8
%r = call i32 %f()
ret i32 %r
}
define i32 @test_valid_null(i64 %i) null_pointer_is_valid {
; CHECK-LABEL: define i32 @test_valid_null(
; CHECK-SAME: i64 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds [3 x ptr], ptr @table3, i64 0, i64 [[I]]
; CHECK-NEXT: [[F:%.*]] = load ptr, ptr [[P]], align 8
; CHECK-NEXT: [[R:%.*]] = call i32 [[F]]()
; CHECK-NEXT: ret i32 [[R]]
;
%p = getelementptr inbounds [3 x ptr], ptr @table3, i64 0, i64 %i
%f = load ptr, ptr %p, align 8
%r = call i32 %f()
ret i32 %r
}
; Null is a valid address in non-zero address spaces.
define i32 @test_valid_null_addrspace(i64 %i) {
; CHECK-LABEL: define i32 @test_valid_null_addrspace(
; CHECK-SAME: i64 [[I:%.*]]) {
; CHECK-NEXT: [[P:%.*]] = getelementptr inbounds [3 x ptr addrspace(1)], ptr @table4, i64 0, i64 [[I]]
; CHECK-NEXT: [[F:%.*]] = load ptr addrspace(1), ptr [[P]], align 8
; CHECK-NEXT: [[R:%.*]] = call addrspace(1) i32 [[F]]()
; CHECK-NEXT: ret i32 [[R]]
;
%p = getelementptr inbounds [3 x ptr addrspace(1)], ptr @table4, i64 0, i64 %i
%f = load ptr addrspace(1), ptr %p, align 8
%r = call addrspace(1) i32 %f()
ret i32 %r
}
;.
; CHECK: [[PROF0]] = !{!"unknown", !"jump-table-to-switch"}
;.