Index: lib/Transforms/Utils/SplitModule.cpp =================================================================== --- lib/Transforms/Utils/SplitModule.cpp +++ lib/Transforms/Utils/SplitModule.cpp @@ -88,6 +88,13 @@ Member = &GV; } + // For aliases we should not separate them from their aliasees regardless + // of linkage. + if (GlobalAlias *GA = dyn_cast(&GV)) { + if (const GlobalObject *Base = GA->getBaseObject()) + GVtoClusterMap.unionSets(&GV, Base); + } + // Further only iterate over local GVs. if (!GV.hasLocalLinkage()) return; Index: test/tools/llvm-split/scc-const-alias.ll =================================================================== --- /dev/null +++ test/tools/llvm-split/scc-const-alias.ll @@ -0,0 +1,38 @@ +; We should never separate alias from aliasee. +; RUN: llvm-split -j=3 -preserve-locals -o %t %s +; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s +; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s +; RUN: llvm-dis -o - %t2 | FileCheck --check-prefix=CHECK2 %s + +; Checks are not critical here - verifier will assert if we fail. +; CHECK0: @g1 = global i32 99 +; CHECK0: @c1Alias = external global i8 +; CHECK0: @g1Alias = internal alias i8, bitcast (i32* @g1 to i8*) + +; CHECK1: @g1 = external global i32 +; CHECK1: @c1Alias = internal alias i8, inttoptr (i64 42 to i8*) + +; Third file is actually empty. +; CHECK2: @g1 = external global i32 +; CHECK2: @g1Alias = external global i8 +; CHECK2: @c1Alias = external global i8 + +@g1 = global i32 99 + +@g1Alias = internal alias i8, bitcast (i32* @g1 to i8*) +@c1Alias = internal alias i8, inttoptr (i64 42 to i8*) +@funExternalAlias = alias i8 (), i8 ()* @funExternal + +define i8 @funExternal() { +entry: + %x = load i8, i8* @g1Alias + ret i8 %x +} + +define i8 @funExternal2() { +entry: + %x = load i8, i8* @c1Alias + %y = call i8 @funExternalAlias() + %z = add i8 %x, %y + ret i8 %z +} Index: test/tools/llvm-split/scc-global-alias.ll =================================================================== --- /dev/null +++ test/tools/llvm-split/scc-global-alias.ll @@ -0,0 +1,47 @@ +; We should never separate alias from aliasee. +; RUN: llvm-split -j=3 -preserve-locals -o %t %s +; RUN: llvm-dis -o - %t0 | FileCheck --check-prefix=CHECK0 %s +; RUN: llvm-dis -o - %t1 | FileCheck --check-prefix=CHECK1 %s +; RUN: llvm-dis -o - %t2 | FileCheck --check-prefix=CHECK2 %s + +; Checks are not critical here - verifier will assert if we fail. +; CHECK0: @funInternal2Alias = alias +; CHECK0: @funExternal2Alias = alias +; CHECK0: define internal i32 @funInternal2 +; CHECK0: define i32 @funExternal2 + +; CHECK1: @funInternalAlias = alias +; CHECK1: define internal i32 @funInternal + +; CHECK2: @funExternalAlias = alias +; CHECK2: define i32 @funExternal + +@funInternalAlias = alias i32 (), i32 ()* @funInternal +@funExternalAlias = alias i32 (), i32 ()* @funExternal +@funInternal2Alias = alias i32 (), i32 ()* @funInternal2 +@funExternal2Alias = alias i32 (), i32 ()* @funExternal2 + +define internal i32 @funInternal() { +entry: + ret i32 0 +} + +define i32 @funExternal() { +entry: + %x = call i32 @funInternalAlias() + ret i32 %x +} + +define internal i32 @funInternal2() { +entry: + %x = call i32 @funInternalAlias() + ret i32 %x +} + +define i32 @funExternal2() { +entry: + %x = call i32 @funInternal2() + %y = call i32 @funExternalAlias() + %z = add nsw i32 %x, %y + ret i32 %z +}