1*bc3e4923SMatt Arsenault; 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 %t 2*bc3e4923SMatt Arsenault; RUN: FileCheck -implicit-check-not=ifunc_remove --check-prefixes=CHECK-FINAL --input-file=%t %s 3*bc3e4923SMatt Arsenault 4*bc3e4923SMatt Arsenaulttarget datalayout = "P1-G2" 5*bc3e4923SMatt Arsenault 6*bc3e4923SMatt Arsenaultdefine void @existing_ctor() addrspace(1) { 7*bc3e4923SMatt Arsenault ret void 8*bc3e4923SMatt Arsenault} 9*bc3e4923SMatt Arsenault 10*bc3e4923SMatt Arsenault; Currently don't support expanding these uses. 11*bc3e4923SMatt Arsenault; CHECK-FINAL: @constant_init_user_addrspace1 = global ptr addrspace(1) @ifunc_remove_used_in_constantinit_as1 12*bc3e4923SMatt Arsenault; CHECK-FINAL: @constant_init_user_addrspace1_cast = global ptr addrspace(1) addrspacecast (ptr @ifunc_remove_used_in_constantinit_as1_cast to ptr addrspace(1)) 13*bc3e4923SMatt Arsenault; CHECK-FINAL: @constant_init_user_addrspace0_cast = global ptr addrspacecast (ptr addrspace(1) @ifunc_remove_used_in_constantinit_as0_cast to ptr) 14*bc3e4923SMatt Arsenault 15*bc3e4923SMatt Arsenault 16*bc3e4923SMatt Arsenault; CHECK-FINAL: [[TABLE:@[0-9]+]] = internal addrspace(2) global [6 x ptr addrspace(1)] poison, align 8 17*bc3e4923SMatt Arsenault 18*bc3e4923SMatt Arsenault; CHECK-FINAL: @llvm.global_ctors = appending addrspace(2) global [2 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }, { i32, ptr addrspace(1), ptr } { i32 10, ptr addrspace(1) [[TABLE_CTOR:@[0-9]+]], ptr null }] 19*bc3e4923SMatt Arsenault@llvm.global_ctors = appending global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 0, ptr addrspace(1) @existing_ctor, ptr null }] 20*bc3e4923SMatt Arsenault 21*bc3e4923SMatt Arsenault 22*bc3e4923SMatt Arsenault 23*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_remove_used_in_constantinit_as1 = ifunc i32 (double), ptr addrspace(1) @resolver1_in_1 24*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_remove_used_in_constantinit_as1_cast = ifunc i32 (double), ptr @resolver1_in_0 25*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_remove_used_in_constantinit_as0_cast = ifunc i32 (double), ptr addrspace(1) @resolver0_in_1 26*bc3e4923SMatt Arsenault 27*bc3e4923SMatt Arsenault@ifunc_remove_used_in_constantinit_as1 = ifunc i32 (double), ptr addrspace(1) @resolver1_in_1 28*bc3e4923SMatt Arsenault@constant_init_user_addrspace1 = global ptr addrspace(1) @ifunc_remove_used_in_constantinit_as1 29*bc3e4923SMatt Arsenault 30*bc3e4923SMatt Arsenault@ifunc_remove_used_in_constantinit_as1_cast = ifunc i32 (double), ptr @resolver1_in_0 31*bc3e4923SMatt Arsenault@constant_init_user_addrspace1_cast = global ptr addrspace(1) addrspacecast (ptr @ifunc_remove_used_in_constantinit_as1_cast to ptr addrspace(1)) 32*bc3e4923SMatt Arsenault 33*bc3e4923SMatt Arsenault@ifunc_remove_used_in_constantinit_as0_cast = ifunc i32 (double), ptr addrspace(1) @resolver0_in_1 34*bc3e4923SMatt Arsenault@constant_init_user_addrspace0_cast = global ptr addrspacecast (ptr addrspace(1) @ifunc_remove_used_in_constantinit_as0_cast to ptr) 35*bc3e4923SMatt Arsenault 36*bc3e4923SMatt Arsenault 37*bc3e4923SMatt Arsenault; CHECK-INTERESTINGNESS: @ifunc_keep_as1_resolver_in_0 38*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_keep_as1_resolver_in_0 = ifunc void (), ptr @resolver1_in_0 39*bc3e4923SMatt Arsenault@ifunc_keep_as1_resolver_in_0 = ifunc void (), ptr @resolver1_in_0 40*bc3e4923SMatt Arsenault@ifunc_remove_as1_resolver_in_0 = ifunc void (), ptr @resolver1_in_0 41*bc3e4923SMatt Arsenault 42*bc3e4923SMatt Arsenault; CHECK-INTERESTINGNESS: @ifunc_keep_as1_resolver_in_1 43*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_keep_as1_resolver_in_1 = ifunc void (), ptr addrspace(1) @resolver1_in_1 44*bc3e4923SMatt Arsenault@ifunc_keep_as1_resolver_in_1 = ifunc void (), ptr addrspace(1) @resolver1_in_1 45*bc3e4923SMatt Arsenault@ifunc_remove_as1_resolver_in_1 = ifunc void (), ptr addrspace(1) @resolver1_in_1 46*bc3e4923SMatt Arsenault 47*bc3e4923SMatt Arsenault; CHECK-INTERESTINGNESS: @ifunc_keep_as1_resolver_casted_in_1 48*bc3e4923SMatt Arsenault; CHECK-FINAL: @ifunc_keep_as1_resolver_casted_in_1 = ifunc void (), addrspacecast (ptr @resolver1_in_0 to ptr addrspace(1)) 49*bc3e4923SMatt Arsenault@ifunc_keep_as1_resolver_casted_in_1 = ifunc void (), ptr addrspace(1) addrspacecast (ptr @resolver1_in_0 to ptr addrspace(1)) 50*bc3e4923SMatt Arsenault@ifunc_remove_as1_resolver_casted_in_1 = ifunc void (), ptr addrspace(1) addrspacecast (ptr @resolver1_in_0 to ptr addrspace(1)) 51*bc3e4923SMatt Arsenault 52*bc3e4923SMatt Arsenault 53*bc3e4923SMatt Arsenaultdefine ptr addrspace(1) @resolver1_in_0() addrspace(0) { 54*bc3e4923SMatt Arsenault ret ptr addrspace(1) inttoptr (i64 123 to ptr addrspace(1)) 55*bc3e4923SMatt Arsenault} 56*bc3e4923SMatt Arsenault 57*bc3e4923SMatt Arsenaultdefine ptr addrspace(1) @resolver1_in_1() addrspace(1) { 58*bc3e4923SMatt Arsenault ret ptr addrspace(1) inttoptr (i64 456 to ptr addrspace(1)) 59*bc3e4923SMatt Arsenault} 60*bc3e4923SMatt Arsenault 61*bc3e4923SMatt Arsenaultdefine ptr addrspace(0) @resolver0_in_1() addrspace(1) { 62*bc3e4923SMatt Arsenault ret ptr addrspace(0) inttoptr (i64 789 to ptr addrspace(0)) 63*bc3e4923SMatt Arsenault} 64*bc3e4923SMatt Arsenault 65*bc3e4923SMatt Arsenaultdefine void @call_removed() addrspace(0) { 66*bc3e4923SMatt Arsenault ; CHECK-FINAL-LABEL: @call_removed( 67*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %1 = load ptr addrspace(1), ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 3), align 8 68*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %2 = addrspacecast ptr addrspace(1) %1 to ptr 69*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: call addrspace(0) void %2() 70*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %3 = load ptr addrspace(1), ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 4), align 8 71*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: call addrspace(1) void %3() 72*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %4 = load ptr addrspace(1), ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 5), align 8 73*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: call addrspace(1) void %4() 74*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: ret void 75*bc3e4923SMatt Arsenault call addrspace(0) void @ifunc_remove_as1_resolver_in_0() 76*bc3e4923SMatt Arsenault call addrspace(1) void @ifunc_remove_as1_resolver_in_1() 77*bc3e4923SMatt Arsenault call addrspace(1) void @ifunc_remove_as1_resolver_casted_in_1() 78*bc3e4923SMatt Arsenault ret void 79*bc3e4923SMatt Arsenault} 80*bc3e4923SMatt Arsenault 81*bc3e4923SMatt Arsenaultdefine void @load_removed() addrspace(0) { 82*bc3e4923SMatt Arsenault ; CHECK-FINAL-LABEL: define void @load_removed( 83*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %load0 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1, align 8 84*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %load1 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1_cast, align 8 85*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: %load2 = load volatile ptr, ptr @constant_init_user_addrspace0_cast, align 8 86*bc3e4923SMatt Arsenault ; CHECK-FINAL-NEXT: ret void 87*bc3e4923SMatt Arsenault %load0 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1 88*bc3e4923SMatt Arsenault %load1 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1_cast 89*bc3e4923SMatt Arsenault %load2 = load volatile ptr, ptr @constant_init_user_addrspace0_cast 90*bc3e4923SMatt Arsenault ret void 91*bc3e4923SMatt Arsenault} 92*bc3e4923SMatt Arsenault 93*bc3e4923SMatt Arsenault; CHECK-FINAL: define internal void [[TABLE_CTOR]]() addrspace(1) { 94*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %1 = call addrspace(1) ptr addrspace(1) @resolver1_in_1() 95*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %1, ptr addrspace(2) [[TABLE]], align 8 96*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %2 = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 97*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %2, ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 1), align 8 98*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %3 = call addrspace(1) ptr @resolver0_in_1() 99*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %4 = addrspacecast ptr %3 to ptr addrspace(1) 100*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %4, ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 2), align 8 101*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %5 = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 102*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %5, ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 3), align 8 103*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %6 = call addrspace(1) ptr addrspace(1) @resolver1_in_1() 104*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %6, ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 4), align 8 105*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: %7 = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 106*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: store ptr addrspace(1) %7, ptr addrspace(2) getelementptr inbounds ([6 x ptr addrspace(1)], ptr addrspace(2) [[TABLE]], i32 0, i32 5), align 8 107*bc3e4923SMatt Arsenault; CHECK-FINAL-NEXT: ret void 108