https://llvm.org/bugs/show_bug.cgi?id=31052
Bug ID: 31052 Summary: ThinLTO + switch table + O2 cause undefined symbols Product: new-bugs Version: trunk Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P Component: new bugs Assignee: unassignedb...@nondot.org Reporter: kra...@google.com CC: llvm-bugs@lists.llvm.org Classification: Unclassified Created attachment 17607 --> https://llvm.org/bugs/attachment.cgi?id=17607&action=edit reproducer Consider the following program that consists of two files (the archive with the sources is attached): main.cc: #include <stdio.h> typedef int (*CallFunc) (); CallFunc GetCallN(int i, int j); int main(void) { printf("%d\n", GetCallN(1, 1)()); printf("%d\n", GetCallN(2, 1)()); } call.cc: typedef int (*CallFunc) (); static int CallX() { return 0; } static int CallY() { return 1; } const CallFunc Funcs0[] = {CallX, CallY, CallY, CallY}; const CallFunc Funcs1[] = {CallY, CallX, CallY, CallY}; const CallFunc Funcs2[] = {CallY, CallY, CallX, CallY}; CallFunc GetCallN(int i, int j) { switch (i) { case 0: return Funcs0[j]; case 1: return Funcs1[j]; case 2: return Funcs2[j]; default: break; } return 0; } Let's build it with ThinLTO and LLD: clang++ -o main main.cc call.cc -O2 -fuse-ld=lld -flto=thin The following error will be displayed: /usr/local/google/home/krasin/src/llvm.org/release-build/bin/ld.lld: error: /tmp/main-fa77ab.o0 (function main): undefined symbol 'CallX() (.llvm.5BF168B0)' /usr/local/google/home/krasin/src/llvm.org/release-build/bin/ld.lld: error: /tmp/main-fa77ab.o0 (function main): undefined symbol 'CallY() (.llvm.5BF168B0)' clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation) - It works correctly with FullLTO: $ clang++ -o main main.cc call.cc -O2 -fuse-ld=lld -flto && ./main 0 1 - It works with a regular build (with lld, as well as ld). - It works with FullLTO + Gold - It fails with ThinLTO + Gold: $ clang++ -o main main.cc call.cc -O2 -fuse-ld=gold -flto=thin /tmp/lto-llvm-22f26f.o:/tmp/main-155d01.o:function main: error: undefined reference to '_ZL5CallXv.llvm.5BF168B0' /tmp/lto-llvm-22f26f.o:/tmp/main-155d01.o:function main: error: undefined reference to '_ZL5CallYv.llvm.5BF168B0' clang-3.9: error: linker command failed with exit code 1 (use -v to see invocation) Looking at the bitcode, -O2 causes the switch statement be converted into a switch table: @_ZL6Funcs0 = internal unnamed_addr constant [4 x i32 ()*] [i32 ()* @_ZL5CallXv, i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallYv], align 16 @_ZL6Funcs1 = internal unnamed_addr constant [4 x i32 ()*] [i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallXv, i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallYv], align 16 @_ZL6Funcs2 = internal unnamed_addr constant [4 x i32 ()*] [i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallYv, i32 ()* @_ZL5CallXv, i32 ()* @_ZL5CallYv], align 16 @switch.table = private unnamed_addr constant [3 x [4 x i32 ()*]*] [[4 x i32 ()*]* @_ZL6Funcs0, [4 x i32 ()*]* @_ZL6Funcs1, [4 x i32 ()*]* @_ZL6Funcs2] ; Function Attrs: norecurse nounwind readonly uwtable define i32 ()* @_Z8GetCallNii(i32 %i, i32 %j) local_unnamed_addr #0 { entry: %0 = icmp ult i32 %i, 3 br i1 %0, label %switch.lookup, label %return switch.lookup: ; preds = %entry %1 = sext i32 %i to i64 %switch.gep = getelementptr inbounds [3 x [4 x i32 ()*]*], [3 x [4 x i32 ()*]*]* @switch.table, i64 0, i64 %1 %switch.load = load [4 x i32 ()*]*, [4 x i32 ()*]** %switch.gep, align 8 %idxprom5 = sext i32 %j to i64 %arrayidx6 = getelementptr inbounds [4 x i32 ()*], [4 x i32 ()*]* %switch.load, i64 0, i64 %idxprom5 %2 = load i32 ()*, i32 ()** %arrayidx6, align 8, !tbaa !1 br label %return return: ; preds = %switch.lookup, %entry %retval.0 = phi i32 ()* [ null, %entry ], [ %2, %switch.lookup ] ret i32 ()* %retval.0 } Whenever I change the code so that the switch table is not generated, it would compile with ThinLTO just fine. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs