Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1996,6 +1996,61 @@ return PPCAsmPrinter::doFinalization(M); } +static std::string convertToSinitAndStermPriority(int Priority) { + // This helper function converts clang init priority to values used in sinit + // and sterm functions. + // + // The conversion strategies are: For [0-100] reserved and [101-65535] + // non-reserved Clang/GNU values, we use linear interpolation to map Clang to + // sinit/sterm priority values. But 21/20 on reserved range ends and 1024 on + // both non-reserved range ends will be used with a factor of 1. A chart as + // the following shows the detailed mapping: + // + // clang sinit/sterm Step + // ========================= reserved range ========================= + // 0 0 + // 1 + // 20 20 + // 16 + // 81 1004 + // 1 + // 100 1023 + // ======================= non-reserved range ======================== + // 101 1024 + // 1 + // 1124 2047 + // 33878 + // 64512 2147482625 + // 1 + // 65535 2147483648 + // + // where: + // - clang is the priority value on init_priority + // - sinit/sterm is the value on the sinit/sterm function + // - Step is the size of step in the sinit/sterm value for each clang value + // in that range. + + if (Priority < 0 || Priority > 65535) + report_fatal_error("invalid init priority"); + + unsigned int P = Priority; + if (P > 20 && P < 81) { + P = 20 + (P - 20) * 16; + } else if (P >= 81 && P <= 1124) { + P = 1004 + (P - 81); + } else if (P > 1124 && P < 64512) { + P = 2047 + (P - 1124) * 33878; + } else if (P >= 64512 && P <= 65535) { + P = 2147482625 + (P - 64512); + } + + std::string PrioritySuffix; + llvm::raw_string_ostream os(PrioritySuffix); + os << llvm::format_hex_no_prefix(P, 8); + os.flush(); + return PrioritySuffix; +} + void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List, bool IsCtor) { SmallVector Structors; @@ -2005,14 +2060,14 @@ unsigned Index = 0; for (Structor &S : Structors) { - if (S.Priority != 65535) - report_fatal_error( - "prioritized sinit and sterm functions are not yet supported on AIX"); + if (const ConstantExpr *CE = dyn_cast(S.Func)) + S.Func = CE->getOperand(0); llvm::GlobalAlias::create( GlobalValue::ExternalLinkage, (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) + - llvm::Twine("80000000_", FormatIndicatorAndUniqueModId) + + llvm::Twine(convertToSinitAndStermPriority(S.Priority)) + + llvm::Twine("_", FormatIndicatorAndUniqueModId) + llvm::Twine("_", llvm::utostr(Index++)), cast(S.Func)); } Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll =================================================================== --- llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll +++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll @@ -1,10 +1,146 @@ -; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s -; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s +; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s -@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }] +@llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 0, void ()* bitcast (i32 (i32)* @cf1 to void ()*), i8* null }, { i32, void ()*, i8* } { i32 21, void ()* @cf2, i8* null }, { i32, void ()*, i8* } { i32 81, void ()* @cf3, i8* null }, { i32, void ()*, i8* } { i32 1125, void ()* @cf4, i8* null }, { i32, void ()*, i8* } { i32 64512, void ()* @cf5, i8* null }] +@llvm.global_dtors = appending global [5 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 20, void ()* bitcast (i32 (i32)* @df1 to void ()*), i8* null }, { i32, void ()*, i8* } { i32 80, void ()* @df2, i8* null }, { i32, void ()*, i8* } { i32 1124, void ()* @df3, i8* null }, { i32, void ()*, i8* } { i32 64511, void ()* @df4, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @df5, i8* null }] -define void @foo() { +define i32 @cf1(i32 %a) { + ret i32 %a +} + +define void @cf2() { + ret void +} + +define void @cf3() { + ret void +} + +define void @cf4() { + ret void +} + +define void @cf5() { ret void } -; CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported +define i32 @df1(i32 %a) { + ret i32 %a +} + +define void @df2() { + ret void +} + +define void @df3() { + ret void +} + +define void @df4() { + ret void +} + +define void @df5() { + ret void +} + +; CHECK: .globl cf1[DS] +; CHECK: .globl .cf1 +; CHECK: .align 2 +; CHECK: .csect cf1[DS] +; CHECK: __sinit00000000_clang_f6a1bc9396775a64c6249effda300afe_0: # @cf1 +; CHECK: .cf1: +; CHECK: .__sinit00000000_clang_f6a1bc9396775a64c6249effda300afe_0: + +; CHECK: .globl cf2[DS] +; CHECK: .globl .cf2 +; CHECK: .align 2 +; CHECK: .csect cf2[DS] +; CHECK: __sinit00000024_clang_f6a1bc9396775a64c6249effda300afe_1: # @cf2 +; CHECK: .cf2: +; CHECK: .__sinit00000024_clang_f6a1bc9396775a64c6249effda300afe_1: + +; CHECK: .globl cf3[DS] +; CHECK: .globl .cf3 +; CHECK: .align 2 +; CHECK: .csect cf3[DS] +; CHECK: __sinit000003ec_clang_f6a1bc9396775a64c6249effda300afe_2: # @cf3 +; CHECK: .cf3: +; CHECK: .__sinit000003ec_clang_f6a1bc9396775a64c6249effda300afe_2: + +; CHECK: .globl cf4[DS] +; CHECK: .globl .cf4 +; CHECK: .align 2 +; CHECK: .csect cf4[DS] +; CHECK: __sinit00008c55_clang_f6a1bc9396775a64c6249effda300afe_3: # @cf4 +; CHECK: .cf4: +; CHECK: .__sinit00008c55_clang_f6a1bc9396775a64c6249effda300afe_3: + +; CHECK: .globl cf5[DS] +; CHECK: .globl .cf5 +; CHECK: .align 2 +; CHECK: .csect cf5[DS] +; CHECK: __sinit7ffffc01_clang_f6a1bc9396775a64c6249effda300afe_4: # @cf5 +; CHECK: .cf5: +; CHECK: .__sinit7ffffc01_clang_f6a1bc9396775a64c6249effda300afe_4: + +; CHECK: .globl df1[DS] +; CHECK: .globl .df1 +; CHECK: .align 2 +; CHECK: .csect df1[DS] +; CHECK: __sterm00000014_clang_f6a1bc9396775a64c6249effda300afe_0: # @df1 +; CHECK: .df1: +; CHECK: .__sterm00000014_clang_f6a1bc9396775a64c6249effda300afe_0: + +; CHECK: .globl df2[DS] +; CHECK: .globl .df2 +; CHECK: .align 2 +; CHECK: .csect df2[DS] +; CHECK: __sterm000003d4_clang_f6a1bc9396775a64c6249effda300afe_1: # @df2 +; CHECK: .df2: +; CHECK: .__sterm000003d4_clang_f6a1bc9396775a64c6249effda300afe_1: + +; CHECK: .globl df3[DS] +; CHECK: .globl .df3 +; CHECK: .align 2 +; CHECK: .csect df3[DS] +; CHECK: __sterm000007ff_clang_f6a1bc9396775a64c6249effda300afe_2: # @df3 +; CHECK: .df3: +; CHECK: .__sterm000007ff_clang_f6a1bc9396775a64c6249effda300afe_2: + +; CHECK: .globl df4[DS] +; CHECK: .globl .df4 +; CHECK: .align 2 +; CHECK: .csect df4[DS] +; CHECK: __sterm7fff2211_clang_f6a1bc9396775a64c6249effda300afe_3: # @df4 +; CHECK: .df4: +; CHECK: .__sterm7fff2211_clang_f6a1bc9396775a64c6249effda300afe_3: + +; CHECK: .globl df5[DS] +; CHECK: .globl .df5 +; CHECK: .align 2 +; CHECK: .csect df5[DS] +; CHECK: __sterm80000000_clang_f6a1bc9396775a64c6249effda300afe_4: # @df5 +; CHECK: .df5: +; CHECK: .__sterm80000000_clang_f6a1bc9396775a64c6249effda300afe_4: + +; CHECK: .globl __sinit00000000_clang_f6a1bc9396775a64c6249effda300afe_0 +; CHECK: .globl .__sinit00000000_clang_f6a1bc9396775a64c6249effda300afe_0 +; CHECK: .globl __sinit00000024_clang_f6a1bc9396775a64c6249effda300afe_1 +; CHECK: .globl .__sinit00000024_clang_f6a1bc9396775a64c6249effda300afe_1 +; CHECK: .globl __sinit000003ec_clang_f6a1bc9396775a64c6249effda300afe_2 +; CHECK: .globl .__sinit000003ec_clang_f6a1bc9396775a64c6249effda300afe_2 +; CHECK: .globl __sinit00008c55_clang_f6a1bc9396775a64c6249effda300afe_3 +; CHECK: .globl .__sinit00008c55_clang_f6a1bc9396775a64c6249effda300afe_3 +; CHECK: .globl __sinit7ffffc01_clang_f6a1bc9396775a64c6249effda300afe_4 +; CHECK: .globl .__sinit7ffffc01_clang_f6a1bc9396775a64c6249effda300afe_4 +; CHECK: .globl __sterm00000014_clang_f6a1bc9396775a64c6249effda300afe_0 +; CHECK: .globl .__sterm00000014_clang_f6a1bc9396775a64c6249effda300afe_0 +; CHECK: .globl __sterm000003d4_clang_f6a1bc9396775a64c6249effda300afe_1 +; CHECK: .globl .__sterm000003d4_clang_f6a1bc9396775a64c6249effda300afe_1 +; CHECK: .globl __sterm000007ff_clang_f6a1bc9396775a64c6249effda300afe_2 +; CHECK: .globl .__sterm000007ff_clang_f6a1bc9396775a64c6249effda300afe_2 +; CHECK: .globl __sterm7fff2211_clang_f6a1bc9396775a64c6249effda300afe_3 +; CHECK: .globl .__sterm7fff2211_clang_f6a1bc9396775a64c6249effda300afe_3 +; CHECK: .globl __sterm80000000_clang_f6a1bc9396775a64c6249effda300afe_4 +; CHECK: .globl .__sterm80000000_clang_f6a1bc9396775a64c6249effda300afe_4