brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · a7853d9 Raw
199 lines · plain
1; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=ifuncs --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t2; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s3 4 5; CHECK-FINAL: @initialized_with_ifunc = global ptr @ifunc_constant_initializer_user6@initialized_with_ifunc = global ptr @ifunc_constant_initializer_user7 8 9; CHECK-FINAL: [[TABLE:@[0-9]+]] = internal global [[[TABLE_SIZE:[0-9]+]] x ptr] poison10; CHECK-FINAL: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 10, ptr @1, ptr null }]11 12 13; CHECK-INTERESTINGNESS: @ifunc_kept1 = ifunc14 15; CHECK-FINAL: @ifunc_kept1 = ifunc void (), ptr @resolver116@ifunc_kept1 = ifunc void (), ptr @resolver117@ifunc_removed2 = ifunc void (), ptr @resolver118 19; CHECK-INTERESTINGNESS: @ifunc_kept3 =20; CHECK-FINAL: @ifunc_kept3 = ifunc i32 (double), ptr @resolver221@ifunc_kept3 = ifunc i32 (double), ptr @resolver222 23 24; Remove one with no users25@ifunc4_removed = ifunc float (i64), ptr @resolver226 27; Keep one with no users28; CHECK-INTERESTINGNESS: @ifunc5_kept = ifunc29@ifunc5_kept = ifunc float (i64), ptr @resolver230 31 32; Make sure the hidden is preserved33; CHECK-INTERESTINGNESS: @ifunc_kept_hidden =34; CHECK-FINAL: @ifunc_kept_hidden = hidden ifunc i32 (double), ptr @resolver335@ifunc_kept_hidden = hidden ifunc i32 (double), ptr @resolver336@ifunc7 = ifunc float (i64), ptr @resolver337 38@ifunc_ptr_arg = ifunc void (ptr), ptr @resolver439 40 41; CHECK-INTERESTINGNESS: @ifunc_nonvoid_kept0 = ifunc42@ifunc_nonvoid_kept0 = ifunc i32 (double), ptr @resolver543@ifunc_nonvoid_removed0 = ifunc i32 (double), ptr @resolver544 45; CHECK-INTERESTINGNESS: @ifunc_nonvoid_kept1 = ifunc46@ifunc_nonvoid_kept1 = ifunc i32 (double), ptr @resolver547@ifunc_nonvoid_removed1 = ifunc i32 (double), ptr @resolver548 49; CHECK-FINAL: @ifunc_constant_initializer_user = ifunc i32 (double), ptr @resolver550@ifunc_constant_initializer_user = ifunc i32 (double), ptr @resolver551 52 53 54define ptr @resolver1() {55  ret ptr inttoptr (i64 123 to ptr)56}57 58define ptr @resolver2() {59  ret ptr inttoptr (i64 456 to ptr)60}61 62define ptr @resolver3() {63  ret ptr inttoptr (i64 789 to ptr)64}65 66define ptr @resolver4() {67  ret ptr inttoptr (i64 999 to ptr)68}69 70define ptr @resolver5() {71  ret ptr inttoptr (i64 420 to ptr)72}73 74define void @call_ifunc_kept1() {75  ; CHECK-FINAL-LABEL: define void @call_ifunc_kept1() {76  ; CHECK-FINAL-NEXT: call void @ifunc_kept1()77  ; CHECK-FINAL-NEXT: ret void78  call void @ifunc_kept1()79  ret void80}81 82; Test call to removed ifunc83define void @call_ifunc_removed(ptr %ptr) {84  ; CHECK-FINAL-LABEL: define void @call_ifunc_removed(ptr %ptr)85  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr @0, align 886  ; CHECK-FINAL-NEXT:  call void %1()87  ; CHECK-FINAL-NEXT:  ret void88  call void @ifunc_removed2()89  ret void90}91 92; Test value use of removed ifunc93define void @store_ifunc_removed2(ptr %ptr) {94  ; CHECK-FINAL-LABEL: define void @store_ifunc_removed2(ptr %ptr) {95  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr [[TABLE]], align 896  ; CHECK-FINAL-NEXT: store ptr %1, ptr %ptr, align 897  ; CHECK-FINAL-NEXT: %2 = load ptr, ptr @0, align 898  ; CHECK-FINAL-NEXT: store ptr %ptr, ptr %2, align 899  ; CHECK-FINAL-NEXT: ret void100  store ptr @ifunc_removed2, ptr %ptr101  store ptr %ptr, ptr @ifunc_removed2102  ret void103}104 105declare void @other_func(ptr)106 107; Check a call user, but not as the call operand108define void @call_ifunc_removed_is_argument(ptr %ptr) {109  ; CHECK-FINAL-LABEL: define void @call_ifunc_removed_is_argument(ptr %ptr) {110  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr [[TABLE]], align 8111  ; CHECK-FINAL-NEXT: call void @other_func(ptr %1)112  ; CHECK-FINAL-NEXT: ret void113  call void @other_func(ptr @ifunc_removed2)114  ret void115}116 117; Check a call user calling the ifunc, and using the ifunc as an argument118define void @call_ifunc_removed_both_call_argument(ptr %ptr) {119  ; CHECK-FINAL-LABEL: define void @call_ifunc_removed_both_call_argument(120  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr getelementptr inbounds ([[[TABLE_SIZE]] x ptr], ptr [[TABLE]], i32 0, i32 3), align 8121  ; CHECK-FINAL-NEXT: %2 = load ptr, ptr getelementptr inbounds ([[[TABLE_SIZE]] x ptr], ptr [[TABLE]], i32 0, i32 3), align 8122  ; CHECK-FINAL-NEXT: call void %1(ptr %1)123  ; CHECK-FINAL-NEXT: ret void124  call void @ifunc_ptr_arg(ptr @ifunc_ptr_arg)125  ret void126}127 128define i32 @call_ifunc_nonvoid(double %arg) {129  ; CHECK-FINAL-LABEL: define i32 @call_ifunc_nonvoid(double %arg) {130  ; CHECK-FINAL-NEXT: %ret0 = call i32 @ifunc_nonvoid_kept0(double %arg)131  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr getelementptr inbounds ([[[TABLE_SIZE]] x ptr], ptr [[TABLE]], i32 0, i32 4), align 8132  ; CHECK-FINAL-NEXT: %ret1 = call i32 %1(double %arg)133  ; CHECK-FINAL-NEXT: %add = add i32 %ret0, %ret1134  ; CHECK-FINAL-NEXT: ret i32 %add135  %ret0 = call i32 @ifunc_nonvoid_kept0(double %arg)136  %ret1 = call i32 @ifunc_nonvoid_removed0(double %arg)137  %add = add i32 %ret0, %ret1138  ret i32 %add139}140 141; Use site is different than ifunc function type142define float @call_different_type_ifunc_nonvoid(double %arg) {143  ; CHECK-FINAL-LABEL: define float @call_different_type_ifunc_nonvoid(double %arg) {144  ; CHECK-FINAL-NEXT: %cast.arg = bitcast double %arg to i64145  ; CHECK-FINAL-NEXT: %ret0 = call float @ifunc_nonvoid_kept0(i64 %cast.arg)146  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr getelementptr inbounds ([[[TABLE_SIZE]] x ptr], ptr [[TABLE]], i32 0, i32 4), align 8147  ; CHECK-FINAL-NEXT: %ret1 = call float %1(i64 %cast.arg)148  ; CHECK-FINAL-NEXT: %fadd = fadd float %ret0, %ret1149  ; CHECK-FINAL-NEXT: ret float %fadd150  %cast.arg = bitcast double %arg to i64151  %ret0 = call float(i64) @ifunc_nonvoid_kept0(i64 %cast.arg)152  %ret1 = call float(i64) @ifunc_nonvoid_removed0(i64 %cast.arg)153  %fadd = fadd float %ret0, %ret1154  ret float %fadd155}156 157; FIXME: Should be able to expand this, but we miss the call158; instruction in the constexpr cast.159define i32 @call_addrspacecast_callee_type_ifunc_nonvoid(double %arg) {160  ; CHECK-FINAL-LABEL: define i32 @call_addrspacecast_callee_type_ifunc_nonvoid(double %arg) {161  ; CHECK-FINAL-NEXT: %ret0 = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_kept1 to ptr addrspace(1))(double %arg)162  ; CHECK-FINAL-NEXT: %ret1 = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_removed1 to ptr addrspace(1))(double %arg)163  ; CHECK-FINAL-NEXT: %add = add i32 %ret0, %ret1164  ; CHECK-FINAL-NEXT: ret i32 %add165  %ret0 = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_kept1 to ptr addrspace(1)) (double %arg)166  %ret1 = call addrspace(1) i32 addrspacecast (ptr @ifunc_nonvoid_removed1 to ptr addrspace(1)) (double %arg)167  %add = add i32 %ret0, %ret1168  ret i32 %add169}170 171define i32 @call_used_in_initializer(double %arg) {172  ; CHECK-FINAL-LABEL: define i32 @call_used_in_initializer(double %arg) {173  ; CHECK-FINAL-NEXT: %1 = load ptr, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 7), align 8174  ; CHECK-FINAL-NEXT: %ret = call i32 %1(double %arg)175  ; CHECK-FINAL-NEXT: ret i32 %ret176  %ret = call i32 @ifunc_constant_initializer_user(double %arg)177  ret i32 %ret178}179 180; CHECK-FINAL-LABEL: define internal void @1() {181; CHECK-FINAL-NEXT: %1 = call ptr @resolver1()182; CHECK-FINAL-NEXT: store ptr %1, ptr @0, align 8183; CHECK-FINAL-NEXT: %2 = call ptr @resolver2()184; CHECK-FINAL-NEXT: store ptr %2, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 1), align 8185; CHECK-FINAL-NEXT: %3 = call ptr @resolver3()186; CHECK-FINAL-NEXT: store ptr %3, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 2), align 8187; CHECK-FINAL-NEXT: %4 = call ptr @resolver4()188; CHECK-FINAL-NEXT: store ptr %4, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 3), align 8189; CHECK-FINAL-NEXT: %5 = call ptr @resolver5()190; CHECK-FINAL-NEXT: store ptr %5, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 4), align 8191; CHECK-FINAL-NEXT: %6 = call ptr @resolver5()192; CHECK-FINAL-NEXT: store ptr %6, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 5), align 8193; CHECK-FINAL-NEXT: %7 = call ptr @resolver5()194; CHECK-FINAL-NEXT: store ptr %7, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 6), align 8195; CHECK-FINAL-NEXT: %8 = call ptr @resolver5()196; CHECK-FINAL-NEXT: store ptr %8, ptr getelementptr inbounds ([8 x ptr], ptr @0, i32 0, i32 7), align 8197; CHECK-FINAL-NEXT: ret void198; CHECK-FINAL-NEXT: }199