From 9d07107b9da9afd672aad16598ffcf6143643deb Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev@hotmail.com>
Date: Tue, 15 Nov 2016 14:15:56 +0000
Subject: [PATCH] Merging r286129:
 ------------------------------------------------------------------------
 r286129 | abataev | 2016-11-07 18:15:02 +0000 (Mon, 07 Nov 2016) | 8 lines

[OPENMP] Fixed codegen for __real/__imag expressions in atomic
constructs.

For __real/__imag unary expressions clang emits lvalue with the
associated type from the original complex expression, but not the
underlying builtin integer or float type. This causes crash in codegen
for atomic constructs, if __real/__imag expression are used in atomic
  constructs.
------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@286965 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGExpr.cpp             | 6 ++++--
 test/OpenMP/atomic_write_codegen.c | 3 +++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 1b782084a91..5f3b290d8eb 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -2248,13 +2248,15 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
       return LV;
     }
 
-    assert(E->getSubExpr()->getType()->isAnyComplexType());
+    QualType T = ExprTy->castAs<ComplexType>()->getElementType();
 
     Address Component =
       (E->getOpcode() == UO_Real
          ? emitAddrOfRealComponent(LV.getAddress(), LV.getType())
          : emitAddrOfImagComponent(LV.getAddress(), LV.getType()));
-    return MakeAddrLValue(Component, ExprTy, LV.getAlignmentSource());
+    LValue ElemLV = MakeAddrLValue(Component, T, LV.getAlignmentSource());
+    ElemLV.getQuals().addQualifiers(LV.getQuals());
+    return ElemLV;
   }
   case UO_PreInc:
   case UO_PreDec: {
diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c
index 66172af07e8..050d7a51056 100644
--- a/test/OpenMP/atomic_write_codegen.c
+++ b/test/OpenMP/atomic_write_codegen.c
@@ -78,6 +78,9 @@ float2 float2x;
 register int rix __asm__("esp");
 
 int main() {
+// CHECK: store atomic i32 1, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @civ, i32 0, i32 1) monotonic,
+#pragma omp atomic write
+ __imag(civ) = 1;
 // CHECK: load i8, i8*
 // CHECK: store atomic i8
 #pragma omp atomic write
-- 
GitLab