1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs 2; RUN: opt -S -passes=lower-ifunc < %s | FileCheck %s 3 4target datalayout = "P1" 5 6; Currently don't support expanding these uses. 7@ifunc_used_in_constantinit_as1 = ifunc i32 (double), ptr addrspace(1) @resolver1_in_1 8@constant_init_user_addrspace1 = global ptr addrspace(1) @ifunc_used_in_constantinit_as1 9 10@ifunc_used_in_constantinit_as1_cast = ifunc i32 (double), ptr @resolver1_in_0 11@constant_init_user_addrspace1_cast = global ptr addrspace(1) addrspacecast (ptr @ifunc_used_in_constantinit_as1_cast to ptr addrspace(1)) 12 13@ifunc_used_in_constantinit_as0_cast = ifunc i32 (double), ptr addrspace(1) @resolver0_in_1 14@constant_init_user_addrspace0_cast = global ptr addrspacecast (ptr addrspace(1) @ifunc_used_in_constantinit_as0_cast to ptr) 15 16 17@ifunc_as1_resolver_in_0 = ifunc void (), ptr @resolver1_in_0 18@ifunc_as1_resolver_in_1 = ifunc void (), ptr addrspace(1) @resolver1_in_1 19@ifunc_as1_resolver_casted_in_1 = ifunc void (), ptr addrspace(1) addrspacecast (ptr @resolver1_in_0 to ptr addrspace(1)) 20 21define ptr addrspace(1) @resolver1_in_0() addrspace(0) { 22 ret ptr addrspace(1) inttoptr (i64 123 to ptr addrspace(1)) 23} 24 25define ptr addrspace(1) @resolver1_in_1() addrspace(1) { 26 ret ptr addrspace(1) inttoptr (i64 456 to ptr addrspace(1)) 27} 28 29define ptr addrspace(0) @resolver0_in_1() addrspace(1) { 30 ret ptr addrspace(0) inttoptr (i64 789 to ptr addrspace(0)) 31} 32 33define void @call_ifuncs() addrspace(0) { 34 call addrspace(0) void @ifunc_as1_resolver_in_0() 35 call addrspace(1) void @ifunc_as1_resolver_in_1() 36 call addrspace(1) void @ifunc_as1_resolver_casted_in_1() 37 ret void 38} 39 40define void @load_ifuncs() addrspace(0) { 41 %load0 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1 42 %load1 = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1_cast 43 %load2 = load volatile ptr, ptr @constant_init_user_addrspace0_cast 44 ret void 45} 46;. 47; CHECK: @[[CONSTANT_INIT_USER_ADDRSPACE1:[a-zA-Z0-9_$"\\.-]+]] = global ptr addrspace(1) @ifunc_used_in_constantinit_as1 48; CHECK: @[[CONSTANT_INIT_USER_ADDRSPACE1_CAST:[a-zA-Z0-9_$"\\.-]+]] = global ptr addrspace(1) addrspacecast (ptr @ifunc_used_in_constantinit_as1_cast to ptr addrspace(1)) 49; CHECK: @[[CONSTANT_INIT_USER_ADDRSPACE0_CAST:[a-zA-Z0-9_$"\\.-]+]] = global ptr addrspacecast (ptr addrspace(1) @ifunc_used_in_constantinit_as0_cast to ptr) 50; CHECK: @[[GLOB0:[0-9]+]] = internal global [6 x ptr addrspace(1)] poison, align 8 51; CHECK: @[[LLVM_GLOBAL_CTORS:[a-zA-Z0-9_$"\\.-]+]] = appending global [1 x { i32, ptr addrspace(1), ptr }] [{ i32, ptr addrspace(1), ptr } { i32 10, ptr addrspace(1) @[[GLOB1:[0-9]+]], ptr null }] 52; CHECK: @[[IFUNC_USED_IN_CONSTANTINIT_AS1:[a-zA-Z0-9_$"\\.-]+]] = ifunc i32 (double), ptr addrspace(1) @resolver1_in_1 53; CHECK: @[[IFUNC_USED_IN_CONSTANTINIT_AS1_CAST:[a-zA-Z0-9_$"\\.-]+]] = ifunc i32 (double), ptr @resolver1_in_0 54; CHECK: @[[IFUNC_USED_IN_CONSTANTINIT_AS0_CAST:[a-zA-Z0-9_$"\\.-]+]] = ifunc i32 (double), ptr addrspace(1) @resolver0_in_1 55;. 56; CHECK-LABEL: define {{[^@]+}}@resolver1_in_0( 57; CHECK-NEXT: ret ptr addrspace(1) inttoptr (i64 123 to ptr addrspace(1)) 58; 59; 60; CHECK-LABEL: define {{[^@]+}}@resolver1_in_1( 61; CHECK-NEXT: ret ptr addrspace(1) inttoptr (i64 456 to ptr addrspace(1)) 62; 63; 64; CHECK-LABEL: define {{[^@]+}}@resolver0_in_1( 65; CHECK-NEXT: ret ptr inttoptr (i64 789 to ptr) 66; 67; 68; CHECK-LABEL: define {{[^@]+}}@call_ifuncs( 69; CHECK-NEXT: [[TMP1:%.*]] = load ptr addrspace(1), ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 3), align 8 70; CHECK-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(1) [[TMP1]] to ptr 71; CHECK-NEXT: call addrspace(0) void [[TMP2]]() 72; CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 4), align 8 73; CHECK-NEXT: call addrspace(1) void [[TMP3]]() 74; CHECK-NEXT: [[TMP4:%.*]] = load ptr addrspace(1), ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 5), align 8 75; CHECK-NEXT: call addrspace(1) void [[TMP4]]() 76; CHECK-NEXT: ret void 77; 78; 79; CHECK-LABEL: define {{[^@]+}}@load_ifuncs( 80; CHECK-NEXT: [[LOAD0:%.*]] = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1, align 8 81; CHECK-NEXT: [[LOAD1:%.*]] = load volatile ptr addrspace(1), ptr @constant_init_user_addrspace1_cast, align 8 82; CHECK-NEXT: [[LOAD2:%.*]] = load volatile ptr, ptr @constant_init_user_addrspace0_cast, align 8 83; CHECK-NEXT: ret void 84; 85; 86; CHECK-LABEL: define {{[^@]+}}@1( 87; CHECK-NEXT: [[TMP1:%.*]] = call addrspace(1) ptr addrspace(1) @resolver1_in_1() 88; CHECK-NEXT: store ptr addrspace(1) [[TMP1]], ptr @[[GLOB0]], align 8 89; CHECK-NEXT: [[TMP2:%.*]] = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 90; CHECK-NEXT: store ptr addrspace(1) [[TMP2]], ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 1), align 8 91; CHECK-NEXT: [[TMP3:%.*]] = call addrspace(1) ptr @resolver0_in_1() 92; CHECK-NEXT: [[TMP4:%.*]] = addrspacecast ptr [[TMP3]] to ptr addrspace(1) 93; CHECK-NEXT: store ptr addrspace(1) [[TMP4]], ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 2), align 8 94; CHECK-NEXT: [[TMP5:%.*]] = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 95; CHECK-NEXT: store ptr addrspace(1) [[TMP5]], ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 3), align 8 96; CHECK-NEXT: [[TMP6:%.*]] = call addrspace(1) ptr addrspace(1) @resolver1_in_1() 97; CHECK-NEXT: store ptr addrspace(1) [[TMP6]], ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 4), align 8 98; CHECK-NEXT: [[TMP7:%.*]] = call addrspace(0) ptr addrspace(1) @resolver1_in_0() 99; CHECK-NEXT: store ptr addrspace(1) [[TMP7]], ptr getelementptr inbounds ([6 x ptr addrspace(1)], ptr @[[GLOB0]], i32 0, i32 5), align 8 100; CHECK-NEXT: ret void 101; 102