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

Reply via email to