llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

Implement support for the Aggregate atomic to non-atomic cast

---
Full diff: https://github.com/llvm/llvm-project/pull/206322.diff


4 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+14-13) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+4-6) 
- (added) clang/test/CIR/CodeGen/agg-atomic-cast.c (+50) 
- (removed) clang/test/CIR/CodeGen/agg-atomic-cast.cpp (-27) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 4d774761b975a..42e027887b9c4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -112,8 +112,8 @@ class AtomicInfo {
   Address convertToAtomicIntPointer(Address addr) const;
 
   /// Turn an atomic-layout object into an r-value.
-  RValue convertAtomicTempToRValue(Address addr, SourceLocation loc,
-                                   bool asValue) const;
+  RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot,
+                                   SourceLocation loc, bool asValue) const;
 
   /// Converts a rvalue to integer value.
   mlir::Value convertRValueToInt(RValue rvalue, mlir::Location loc,
@@ -211,15 +211,13 @@ Address AtomicInfo::convertToAtomicIntPointer(Address 
addr) const {
   return castToAtomicIntPointer(addr);
 }
 
-RValue AtomicInfo::convertAtomicTempToRValue(Address addr, SourceLocation loc,
+RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
+                                             AggValueSlot resultSlot,
+                                             SourceLocation loc,
                                              bool asValue) const {
   if (lvalue.isSimple()) {
-    if (evaluationKind == TEK_Aggregate) {
-      cgf.cgm.errorNYI(
-          loc,
-          "AtomicInfo::convertAtomicTempToRValue: evaluationKind is 
aggregate");
-      return RValue::get(nullptr);
-    }
+    if (evaluationKind == TEK_Aggregate)
+      return resultSlot.asRValue();
 
     // Drill into the padding structure if we have one.
     if (hasPadding()) {
@@ -384,17 +382,20 @@ RValue AtomicInfo::convertToValueOrAtomic(mlir::Value 
intVal,
   // Create a temporary.  This needs to be big enough to hold the
   // atomic integer.
   Address temp = Address::invalid();
+  bool tempIsVolatile = false;
   if (asValue && getEvaluationKind() == TEK_Aggregate) {
-    cgf.cgm.errorNYI("convertToValueOrAtomic: temporary aggregate");
-    return RValue::get(nullptr);
+    assert(!resultSlot.isIgnored());
+    temp = resultSlot.getAddress();
+    tempIsVolatile = resultSlot.isVolatile();
   } else {
     temp = createTempAlloca();
   }
 
   // Slam the integer into the temporary.
   Address castTemp = castToAtomicIntPointer(temp);
-  cgf.getBuilder().createStore(cgf.getLoc(loc), intVal, castTemp);
-  return convertAtomicTempToRValue(temp, loc, asValue);
+  cgf.getBuilder().createStore(cgf.getLoc(loc), intVal, castTemp,
+                               tempIsVolatile);
+  return convertAtomicTempToRValue(temp, resultSlot, loc, asValue);
 }
 
 /// Copy an r-value into memory as part of storing to an atomic type.
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 4d54519e4d25f..75435696ef915 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -262,11 +262,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
     case CK_NonAtomicToAtomic:
     case CK_AtomicToNonAtomic: {
       bool isToAtomic = (e->getCastKind() == CK_NonAtomicToAtomic);
-      if (!isToAtomic) {
-        cgf.cgm.errorNYI(e->getSourceRange(),
-                         "AggExprEmitter: CK_AtomicToNonAtomic");
-        return;
-      }
 
       // Determine the atomic and value types.
       QualType atomicType = e->getSubExpr()->getType();
@@ -691,7 +686,10 @@ void AggExprEmitter::emitAggLoadOfLValue(const Expr *e) {
   LValue lv = cgf.emitLValue(e);
 
   // If the type of the l-value is atomic, then do an atomic load.
-  assert(!cir::MissingFeatures::opLoadStoreAtomic());
+  if (lv.getType()->isAtomicType() || cgf.isLValueSuitableForInlineAtomic(lv)) 
{
+    cgf.emitAtomicLoad(lv, e->getExprLoc(), dest);
+    return;
+  }
 
   emitFinalDestCopy(e->getType(), lv);
 }
diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.c 
b/clang/test/CIR/CodeGen/agg-atomic-cast.c
new file mode 100644
index 0000000000000..f9af8ae317e03
--- /dev/null
+++ b/clang/test/CIR/CodeGen/agg-atomic-cast.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+typedef struct S {
+  int x;
+} S;
+
+void non_atomic_to_atomic_cast() {
+  S s;
+  _Atomic(S) as =  s;
+}
+
+// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S>
+// CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S>
+// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S>
+
+// LLVM:  %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4
+// LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 4
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], 
i64 4, i1 false)
+
+// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4
+// OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 4
+// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[SA_ADDR]], ptr align 
4 %[[S_ADDR]], i64 4, i1 false)
+
+void atomic_to_non_atomic_cast() {
+  _Atomic S as;
+  S s;
+  s = as;
+}
+
+// CIR: %[[AS_ADDR:.*]] = cir.alloca "as" {{.*}} : !cir.ptr<!rec_S>
+// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S>
+// CIR: %[[SA_PTR:.*]] = cir.cast bitcast %[[AS_ADDR]] : !cir.ptr<!rec_S> -> 
!cir.ptr<!u32i>
+// CIR: %[[ATOMIC_LOAD:.*]] = cir.load {{.*}} atomic(seq_cst) %[[SA_PTR]] : 
!cir.ptr<!u32i>, !u32i
+// CIR: %[[S_PTR:.*]] = cir.cast bitcast %[[S_ADDR]] : !cir.ptr<!rec_S> -> 
!cir.ptr<!u32i>
+// CIR: cir.store {{.*}} %[[ATOMIC_LOAD]], %[[S_PTR]] : !u32i, !cir.ptr<!u32i>
+
+// LLVM: %[[AS_ADDR:.*]] = alloca %struct.S, i64 1, align 4
+// LLVM: %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4
+// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i32, ptr %[[AS_ADDR]] seq_cst, 
align 4
+// LLVM: store i32 %[[ATOMIC_LOAD]], ptr %[[S_ADDR]], align 4
+
+// OGCG: %[[AS_ADDR:.*]] = alloca %struct.S, align 4
+// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4
+// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic i32, ptr %[[AS_ADDR]] seq_cst, 
align 4
+// OGCG: store i32 %[[ATOMIC_LOAD]], ptr %[[S_ADDR]], align 4
diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp 
b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
deleted file mode 100644
index 12ed04f14edf2..0000000000000
--- a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-Wno-unused-value -fclangir -emit-cir %s -o %t.cir
-// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
-// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-Wno-unused-value -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
-
-struct S {
-  int data[4];
-};
-
-void non_atomic_to_atomic_cast() {
-  S s;
-  _Atomic(S) as =  s;
-}
-
-// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S>
-// CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S>
-// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S>
-
-// LLVM:  %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4
-// LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 16
-// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], 
i64 16, i1 false)
-
-// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4
-// OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 16
-// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[SA_ADDR]], ptr align 
4 %[[S_ADDR]], i64 16, i1 false)

``````````

</details>


https://github.com/llvm/llvm-project/pull/206322
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to