ahatanak created this revision. ahatanak added a reviewer: rjmccall. ahatanak added a subscriber: cfe-commits.
r246985 made changes to give a higher alignment for exception objects on the grounds that Itanium says _Unwind_Exception should be "double-word" aligned and the structure is normally declared with __attribute__((aligned)) guaranteeing 16-byte alignment. It turns out that libc++abi doesn't declare the structure with __attribute__((aligned)) and therefore only guarantees 8-byte alignment on 32-bit and 64-bit platforms. This caused a crash in some cases when the backend emitted SIMD store instructions that requires 16-byte alignment (such as movaps). This patch makes ItaniumCXXABI::getAlignmentOfExnObject return an 8-byte alignment on Darwin to fix the crash. http://reviews.llvm.org/D18479 Files: lib/CodeGen/ItaniumCXXABI.cpp test/CodeGenCXX/eh.cpp Index: test/CodeGenCXX/eh.cpp =================================================================== --- test/CodeGenCXX/eh.cpp +++ test/CodeGenCXX/eh.cpp @@ -448,5 +448,27 @@ } } +namespace test17 { +class BaseException { +private: + int a[4]; +public: + BaseException() {}; +}; + +class DerivedException: public BaseException { +}; + +int foo() { + throw DerivedException(); + // The alignment passed to memset is 8, not 16, on Darwin. + + // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16) + // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"* + // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8* + // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false) +} +} + // CHECK: attributes [[NUW]] = { nounwind } // CHECK: attributes [[NR]] = { noreturn } Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -163,8 +163,17 @@ /// we assume that alignment here. (It's generally 16 bytes, but /// some targets overwrite it.) CharUnits getAlignmentOfExnObject() { - auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned(); - return CGM.getContext().toCharUnitsFromBits(align); + unsigned Align; + + // Alignment is 8 for darwin since libc++abi doesn't declare + // _Unwind_Exception with __attribute__((aligned)) and therefore doesn't + // guarantee 16-byte alignment. + if (CGM.getContext().getTargetInfo().getTriple().isOSDarwin()) + Align = 64; + else + Align = CGM.getContext().getTargetDefaultAlignForAttributeAligned(); + + return CGM.getContext().toCharUnitsFromBits(Align); } void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
Index: test/CodeGenCXX/eh.cpp =================================================================== --- test/CodeGenCXX/eh.cpp +++ test/CodeGenCXX/eh.cpp @@ -448,5 +448,27 @@ } } +namespace test17 { +class BaseException { +private: + int a[4]; +public: + BaseException() {}; +}; + +class DerivedException: public BaseException { +}; + +int foo() { + throw DerivedException(); + // The alignment passed to memset is 8, not 16, on Darwin. + + // CHECK: [[T0:%.*]] = call i8* @__cxa_allocate_exception(i64 16) + // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to %"class.test17::DerivedException"* + // CHECK-NEXT: [[T2:%.*]] = bitcast %"class.test17::DerivedException"* [[T1]] to i8* + // CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* [[T2]], i8 0, i64 16, i32 8, i1 false) +} +} + // CHECK: attributes [[NUW]] = { nounwind } // CHECK: attributes [[NR]] = { noreturn } Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -163,8 +163,17 @@ /// we assume that alignment here. (It's generally 16 bytes, but /// some targets overwrite it.) CharUnits getAlignmentOfExnObject() { - auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned(); - return CGM.getContext().toCharUnitsFromBits(align); + unsigned Align; + + // Alignment is 8 for darwin since libc++abi doesn't declare + // _Unwind_Exception with __attribute__((aligned)) and therefore doesn't + // guarantee 16-byte alignment. + if (CGM.getContext().getTargetInfo().getTriple().isOSDarwin()) + Align = 64; + else + Align = CGM.getContext().getTargetDefaultAlignForAttributeAligned(); + + return CGM.getContext().toCharUnitsFromBits(Align); } void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits