brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 95fbe5b Raw
192 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs2; RUN: opt -S -passes=lower-ifunc < %s | FileCheck %s3 4@initialized_with_ifunc = global ptr @ifunc_constant_initializer_user5 6@ifunc_1 = ifunc void (), ptr @resolver17@ifunc_2 = ifunc void (), ptr @resolver18 9 10; Keep one with no users11@ifunc_no_users = ifunc float (i64), ptr @resolver212 13 14@ifunc7 = ifunc float (i64), ptr @resolver315@ifunc_ptr_arg = ifunc void (ptr), ptr @resolver416 17@ifunc_nonvoid_0 = ifunc i32 (double), ptr @resolver518@ifunc_nonvoid_1 = ifunc i32 (double), ptr @resolver519@ifunc_constant_initializer_user = ifunc i32 (double), ptr @resolver520 21define ptr @resolver1() {22  ret ptr inttoptr (i64 123 to ptr)23}24 25define ptr @resolver2() {26  ret ptr inttoptr (i64 456 to ptr)27}28 29define ptr @resolver3() {30  ret ptr inttoptr (i64 789 to ptr)31}32 33define ptr @resolver4() {34  ret ptr inttoptr (i64 999 to ptr)35}36 37define ptr @resolver5() {38  ret ptr inttoptr (i64 420 to ptr)39}40 41 42; Test call to  ifunc43define void @call_ifunc(ptr %ptr) {44  call void @ifunc_1()45  call void @ifunc_2()46  ret void47}48 49; Test value use of  ifunc50define void @store_ifunc_2(ptr %ptr) {51  store ptr @ifunc_2, ptr %ptr52  store ptr %ptr, ptr @ifunc_253  ret void54}55 56declare void @other_func(ptr)57 58; Check a call user, but not as the call operand59define void @call_ifunc_is_argument(ptr %ptr) {60  call void @other_func(ptr @ifunc_2)61  ret void62}63 64; Check a call user calling the ifunc, and using the ifunc as an argument65define void @call_ifunc_both_call_argument(ptr %ptr) {66  call void @ifunc_ptr_arg(ptr @ifunc_ptr_arg)67  ret void68}69 70define i32 @call_ifunc_nonvoid(double %arg) {71  %ret = call i32 @ifunc_nonvoid_0(double %arg)72  ret i32 %ret73}74 75; Use site is different than ifunc function type76define float @call_different_type_ifunc_nonvoid(double %arg) {77  %cast.arg = bitcast double %arg to i6478  %ret = call float(i64) @ifunc_nonvoid_0(i64 %cast.arg)79  ret float %ret80}81 82; FIXME: Should be able to expand this, but we miss the call83; instruction in the constexpr cast.84define i32 @call_addrspacecast_callee_type_ifunc_nonvoid(double %arg) {85  %ret = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_1 to ptr addrspace(1)) (double %arg)86  ret i32 %ret87}88 89define i32 @call_used_in_initializer(double %arg) {90  %ret = call i32 @ifunc_constant_initializer_user(double %arg)91  ret i32 %ret92}93;.94; CHECK: @[[INITIALIZED_WITH_IFUNC:[a-zA-Z0-9_$"\\.-]+]] = global ptr @ifunc_constant_initializer_user95; CHECK: @[[GLOB0:[0-9]+]] = internal global [8 x ptr] poison, align 896; CHECK: @[[LLVM_GLOBAL_CTORS:[a-zA-Z0-9_$"\\.-]+]] = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 10, ptr @[[GLOB1:[0-9]+]], ptr null }]97; CHECK: @[[IFUNC_NONVOID_1:[a-zA-Z0-9_$"\\.-]+]] = ifunc i32 (double), ptr @resolver598; CHECK: @[[IFUNC_CONSTANT_INITIALIZER_USER:[a-zA-Z0-9_$"\\.-]+]] = ifunc i32 (double), ptr @resolver599;.100; CHECK-LABEL: define {{[^@]+}}@resolver1(101; CHECK-NEXT:    ret ptr inttoptr (i64 123 to ptr)102;103;104; CHECK-LABEL: define {{[^@]+}}@resolver2(105; CHECK-NEXT:    ret ptr inttoptr (i64 456 to ptr)106;107;108; CHECK-LABEL: define {{[^@]+}}@resolver3(109; CHECK-NEXT:    ret ptr inttoptr (i64 789 to ptr)110;111;112; CHECK-LABEL: define {{[^@]+}}@resolver4(113; CHECK-NEXT:    ret ptr inttoptr (i64 999 to ptr)114;115;116; CHECK-LABEL: define {{[^@]+}}@resolver5(117; CHECK-NEXT:    ret ptr inttoptr (i64 420 to ptr)118;119;120; CHECK-LABEL: define {{[^@]+}}@call_ifunc(121; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr @[[GLOB0]], align 8122; CHECK-NEXT:    call void [[TMP1]]()123; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 1), align 8124; CHECK-NEXT:    call void [[TMP2]]()125; CHECK-NEXT:    ret void126;127;128; CHECK-LABEL: define {{[^@]+}}@store_ifunc_2(129; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 1), align 8130; CHECK-NEXT:    store ptr [[TMP1]], ptr [[PTR:%.*]], align 8131; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 1), align 8132; CHECK-NEXT:    store ptr [[PTR]], ptr [[TMP2]], align 8133; CHECK-NEXT:    ret void134;135;136; CHECK-LABEL: define {{[^@]+}}@call_ifunc_is_argument(137; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 1), align 8138; CHECK-NEXT:    call void @other_func(ptr [[TMP1]])139; CHECK-NEXT:    ret void140;141;142; CHECK-LABEL: define {{[^@]+}}@call_ifunc_both_call_argument(143; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 4), align 8144; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 4), align 8145; CHECK-NEXT:    call void [[TMP1]](ptr [[TMP1]])146; CHECK-NEXT:    ret void147;148;149; CHECK-LABEL: define {{[^@]+}}@call_ifunc_nonvoid(150; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 5), align 8151; CHECK-NEXT:    [[RET:%.*]] = call i32 [[TMP1]](double [[ARG:%.*]])152; CHECK-NEXT:    ret i32 [[RET]]153;154;155; CHECK-LABEL: define {{[^@]+}}@call_different_type_ifunc_nonvoid(156; CHECK-NEXT:    [[CAST_ARG:%.*]] = bitcast double [[ARG:%.*]] to i64157; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 5), align 8158; CHECK-NEXT:    [[RET:%.*]] = call float [[TMP1]](i64 [[CAST_ARG]])159; CHECK-NEXT:    ret float [[RET]]160;161;162; CHECK-LABEL: define {{[^@]+}}@call_addrspacecast_callee_type_ifunc_nonvoid(163; CHECK-NEXT:    [[RET:%.*]] = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_1 to ptr addrspace(1))(double [[ARG:%.*]])164; CHECK-NEXT:    ret i32 [[RET]]165;166;167; CHECK-LABEL: define {{[^@]+}}@call_used_in_initializer(168; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 7), align 8169; CHECK-NEXT:    [[RET:%.*]] = call i32 [[TMP1]](double [[ARG:%.*]])170; CHECK-NEXT:    ret i32 [[RET]]171;172;173; CHECK-LABEL: define {{[^@]+}}@1(174; CHECK-NEXT:    [[TMP1:%.*]] = call ptr @resolver1()175; CHECK-NEXT:    store ptr [[TMP1]], ptr @[[GLOB0]], align 8176; CHECK-NEXT:    [[TMP2:%.*]] = call ptr @resolver1()177; CHECK-NEXT:    store ptr [[TMP2]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 1), align 8178; CHECK-NEXT:    [[TMP3:%.*]] = call ptr @resolver2()179; CHECK-NEXT:    store ptr [[TMP3]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 2), align 8180; CHECK-NEXT:    [[TMP4:%.*]] = call ptr @resolver3()181; CHECK-NEXT:    store ptr [[TMP4]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 3), align 8182; CHECK-NEXT:    [[TMP5:%.*]] = call ptr @resolver4()183; CHECK-NEXT:    store ptr [[TMP5]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 4), align 8184; CHECK-NEXT:    [[TMP6:%.*]] = call ptr @resolver5()185; CHECK-NEXT:    store ptr [[TMP6]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 5), align 8186; CHECK-NEXT:    [[TMP7:%.*]] = call ptr @resolver5()187; CHECK-NEXT:    store ptr [[TMP7]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 6), align 8188; CHECK-NEXT:    [[TMP8:%.*]] = call ptr @resolver5()189; CHECK-NEXT:    store ptr [[TMP8]], ptr getelementptr inbounds ([8 x ptr], ptr @[[GLOB0]], i32 0, i32 7), align 8190; CHECK-NEXT:    ret void191;192