[cfe-commits] r133261 - in /cfe/trunk: lib/CodeGen/CGExprAgg.cpp test/CodeGen/compound-literal.c

Douglas Gregor dgregor at apple.com
Fri Jun 17 09:37:20 PDT 2011


Author: dgregor
Date: Fri Jun 17 11:37:20 2011
New Revision: 133261

URL: http://llvm.org/viewvc/llvm-project?rev=133261&view=rev
Log:
When emitting a compound literal of POD type, continue to emit a
separate aggregate temporary and then memcpy it over to the
destination. This fixes a regression I introduced with r133235, where
the compound literal on the RHS of an assignment makes use of the
structure on the LHS of the assignment.

I'm deeply suspicious of AggExprEmitter::VisitBinAssign()'s
optimization where it emits the RHS of an aggregate assignment
directly into the LHS lvalue without checking whether there is any
aliasing between the LHS/RHS. However, I'm not in a position to
revisit this now.

Big thanks to Eli for finding the regression!

Modified:
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/test/CodeGen/compound-literal.c

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=133261&r1=133260&r2=133261&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Fri Jun 17 11:37:20 2011
@@ -247,6 +247,16 @@
 
 void
 AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  if (E->getType().isPODType(CGF.getContext())) {
+    // For a POD type, just emit a load of the lvalue + a copy, because our
+    // compound literal might alias the destination.
+    // FIXME: This is a band-aid; the real problem appears to be in our handling
+    // of assignments, where we store directly into the LHS without checking
+    // whether anything in the RHS aliases.
+    EmitAggLoadOfLValue(E);
+    return;
+  }
+  
   AggValueSlot Slot = EnsureSlot(E->getType());
   CGF.EmitAggExpr(E->getInitializer(), Slot);
 }

Modified: cfe/trunk/test/CodeGen/compound-literal.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/compound-literal.c?rev=133261&r1=133260&r2=133261&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/compound-literal.c (original)
+++ cfe/trunk/test/CodeGen/compound-literal.c Fri Jun 17 11:37:20 2011
@@ -1,12 +1,33 @@
-// RUN: %clang_cc1 < %s -emit-llvm
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
 
 int* a = &(int){1};
 struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
 // Not working; complex constants are broken
 // _Complex double * x = &(_Complex double){1.0f};
 
-int xxx() {
+void xxx() {
 int* a = &(int){1};
 struct s {int a, b, c;} * b = &(struct s) {1, 2, 3};
 _Complex double * x = &(_Complex double){1.0f};
 }
+
+// CHECK: define void @f()
+void f() {
+  typedef struct S { int x,y; } S;
+  // CHECK: [[S:%[a-zA-Z0-9.]+]] = alloca [[STRUCT:%[a-zA-Z0-9.]+]],
+  struct S s;
+  // CHECK-NEXT: [[COMPOUNDLIT:%[a-zA-Z0-9.]+]] = alloca [[STRUCT]]
+  // CHECK-NEXT: [[CX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 0
+  // CHECK-NEXT: [[SY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[S]], i32 0, i32 1
+  // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32* [[SY]]
+  // CHECK-NEXT: store i32 [[TMP]], i32* [[CX]]
+  // CHECK-NEXT: [[CY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 1
+  // CHECK-NEXT: [[SX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]]* [[S]], i32 0, i32 0
+  // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32* [[SX]]
+  // CHECK-NEXT: store i32 [[TMP]], i32* [[CY]]
+  // CHECK-NEXT: [[SI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[S]] to i8*
+  // CHECK-NEXT: [[COMPOUNDLITI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[COMPOUNDLIT]] to i8*
+  // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SI8]], i8* [[COMPOUNDLITI8]], i64 8, i32 4, i1 false)
+  s = (S){s.y,s.x};
+  // CHECK-NEXT: ret void
+}





More information about the cfe-commits mailing list