Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -7651,7 +7651,8 @@ functions, priorities, and an associated global or function. The functions referenced by this array will be called in ascending order of priority (i.e. lowest first) when the module is loaded. The order of -functions with the same priority is not defined. +functions with the same priority is given by the order of their appearance +in the array. If the third field is non-null, and points to a global variable or function, the initializer function will only run if the associated @@ -7671,7 +7672,8 @@ functions, priorities, and an associated global or function. The functions referenced by this array will be called in descending order of priority (i.e. highest first) when the module is unloaded. The -order of functions with the same priority is not defined. +order of functions with the same priority is given by the order of their +appearance in the array. If the third field is non-null, and points to a global variable or function, the destructor function will only run if the associated Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2306,6 +2306,11 @@ if (Structors.empty()) return; + // Emit the structors in reverse order if we are using the .ctor/.dtor + // initialization scheme. + if (!TM.Options.UseInitArray) + std::reverse(Structors.begin(), Structors.end()); + const Align Align = DL.getPointerPrefAlignment(); for (Structor &S : Structors) { const TargetLoweringObjectFile &Obj = getObjFileLowering(); Index: llvm/test/CodeGen/SPARC/constructor.ll =================================================================== --- llvm/test/CodeGen/SPARC/constructor.ll +++ llvm/test/CodeGen/SPARC/constructor.ll @@ -14,12 +14,12 @@ ret void } -; CTOR: .section .ctors.65520,#alloc,#write -; CTOR-NEXT: .p2align 2 -; CTOR-NEXT: .word g -; CTOR-NEXT: .section .ctors,#alloc,#write +; CTOR: .section .ctors,#alloc,#write ; CTOR-NEXT: .p2align 2 ; CTOR-NEXT: .word f +; CTOR-NEXT: .section .ctors.65520,#alloc,#write +; CTOR-NEXT: .p2align 2 +; CTOR-NEXT: .word g ; INIT-ARRAY: .section .init_array.15,#alloc,#write ; INIT-ARRAY-NEXT: .p2align 2 Index: llvm/test/CodeGen/X86/2011-08-29-InitOrder.ll =================================================================== --- llvm/test/CodeGen/X86/2011-08-29-InitOrder.ll +++ llvm/test/CodeGen/X86/2011-08-29-InitOrder.ll @@ -3,24 +3,24 @@ ; PR5329 @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 2000, void ()* @construct_2, i8* null }, { i32, void ()*, i8* } { i32 3000, void ()* @construct_3, i8* null }, { i32, void ()*, i8* } { i32 1000, void ()* @construct_1, i8* null }] -; CHECK-DEFAULT: .section .ctors.64535,"aw",@progbits -; CHECK-DEFAULT: .long construct_1 -; CHECK-DEFAULT: .section .ctors.63535,"aw",@progbits -; CHECK-DEFAULT: .long construct_2 ; CHECK-DEFAULT: .section .ctors.62535,"aw",@progbits ; CHECK-DEFAULT: .long construct_3 +; CHECK-DEFAULT: .section .ctors.63535,"aw",@progbits +; CHECK-DEFAULT: .long construct_2 +; CHECK-DEFAULT: .section .ctors.64535,"aw",@progbits +; CHECK-DEFAULT: .long construct_1 ; CHECK-DARWIN: .long _construct_1 ; CHECK-DARWIN-NEXT: .long _construct_2 ; CHECK-DARWIN-NEXT: .long _construct_3 @llvm.global_dtors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 2000, void ()* @destruct_2, i8* null }, { i32, void ()*, i8* } { i32 1000, void ()* @destruct_1, i8* null }, { i32, void ()*, i8* } { i32 3000, void ()* @destruct_3, i8* null }] -; CHECK-DEFAULT: .section .dtors.64535,"aw",@progbits -; CHECK-DEFAULT: .long destruct_1 -; CHECK-DEFAULT: .section .dtors.63535,"aw",@progbits -; CHECK-DEFAULT: .long destruct_2 ; CHECK-DEFAULT: .section .dtors.62535,"aw",@progbits ; CHECK-DEFAULT: .long destruct_3 +; CHECK-DEFAULT: .section .dtors.63535,"aw",@progbits +; CHECK-DEFAULT: .long destruct_2 +; CHECK-DEFAULT: .section .dtors.64535,"aw",@progbits +; CHECK-DEFAULT: .long destruct_1 ; CHECK-DARWIN: .long _destruct_1 ; CHECK-DARWIN-NEXT: .long _destruct_2 Index: llvm/test/CodeGen/X86/constructor.ll =================================================================== --- llvm/test/CodeGen/X86/constructor.ll +++ llvm/test/CodeGen/X86/constructor.ll @@ -9,7 +9,7 @@ ; RUN: llc -mtriple i586-intel-elfiamcu -use-ctors < %s | FileCheck %s --check-prefix=MCU-CTORS ; RUN: llc -mtriple i586-intel-elfiamcu < %s | FileCheck %s --check-prefix=MCU-INIT-ARRAY ; RUN: llc -mtriple x86_64-win32-gnu < %s | FileCheck --check-prefix=COFF-CTOR %s -@llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null}, { i32, void ()*, i8* } { i32 15, void ()* @g, i8* @v }, { i32, void ()*, i8* } { i32 55555, void ()* @h, i8* @v }] +@llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null}, { i32, void ()*, i8* } { i32 15, void ()* @g, i8* @v }, { i32, void ()*, i8* } { i32 55555, void ()* @h, i8* @v }, { i32, void ()*, i8* } { i32 65535, void ()* @i, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @j, i8* null }] @v = weak_odr global i8 0 @@ -28,15 +28,27 @@ ret void } -; CTOR: .section .ctors.65520,"aGw",@progbits,v,comdat +define void @i() { +entry: + ret void +} + +define void @j() { +entry: + ret void +} + +; CTOR: .section .ctors,"aw",@progbits ; CTOR-NEXT: .p2align 3 -; CTOR-NEXT: .quad g +; CTOR-NEXT: .quad j +; CTOR-NEXT: .quad i +; CTOR-NEXT: .quad f ; CTOR-NEXT: .section .ctors.09980,"aGw",@progbits,v,comdat ; CTOR-NEXT: .p2align 3 ; CTOR-NEXT: .quad h -; CTOR-NEXT: .section .ctors,"aw",@progbits +; CTOR-NEXT: .section .ctors.65520,"aGw",@progbits,v,comdat ; CTOR-NEXT: .p2align 3 -; CTOR-NEXT: .quad f +; CTOR-NEXT: .quad g ; INIT-ARRAY: .section .init_array.15,"aGw",@init_array,v,comdat ; INIT-ARRAY-NEXT: .p2align 3 @@ -47,6 +59,8 @@ ; INIT-ARRAY-NEXT: .section .init_array,"aw",@init_array ; INIT-ARRAY-NEXT: .p2align 3 ; INIT-ARRAY-NEXT: .quad f +; INIT-ARRAY-NEXT: .quad i +; INIT-ARRAY-NEXT: .quad j ; NACL: .section .init_array.15,"aGw",@init_array,v,comdat ; NACL-NEXT: .p2align 2 @@ -57,6 +71,8 @@ ; NACL-NEXT: .section .init_array,"aw",@init_array ; NACL-NEXT: .p2align 2 ; NACL-NEXT: .long f +; NACL-NEXT: .long i +; NACL-NEXT: .long j ; MCU-CTORS: .section .ctors,"aw",@progbits ; MCU-INIT-ARRAY: .section .init_array,"aw",@init_array @@ -70,3 +86,5 @@ ; COFF-CTOR-NEXT: .section .ctors,"dw" ; COFF-CTOR-NEXT: .p2align 3 ; COFF-CTOR-NEXT: .quad f +; COFF-CTOR-NEXT: .quad i +; COFF-CTOR-NEXT: .quad j