https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/192152

Similar to the previous Expr-change that I made, this does the same with 
pointers-to-arrays (and other types).  The new implementation is effectively a 
copy/paste of the classic-codegen, so it maintains our current 
invariants/assumptions about changes via emitLoadOfLValue.

>From dcd32d3ed3ac77a103f41826dff54d6b010323db Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Tue, 14 Apr 2026 15:44:16 -0700
Subject: [PATCH] [CIR] Handle scalar lowering of qualification-changes

Similar to the previous Expr-change that I made, this does the same with
pointers-to-arrays (and other types).  The new implementation is
effectively a copy/paste of the classic-codegen, so it maintains our
current invariants/assumptions about changes via emitLoadOfLValue.
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 15 +++------------
 clang/test/CIR/CodeGen/cast-cxx20.cpp      | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index b1498f376725d..f8d29dc7da1b3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2144,18 +2144,9 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr 
*ce) {
   case CK_NonAtomicToAtomic:
   case CK_UserDefinedConversion:
     return Visit(const_cast<Expr *>(subExpr));
-  case CK_NoOp: {
-    auto v = Visit(const_cast<Expr *>(subExpr));
-    if (v) {
-      // CK_NoOp can model a pointer qualification conversion, which can remove
-      // an array bound and change the IR type.
-      // FIXME: Once pointee types are removed from IR, remove this.
-      mlir::Type t = cgf.convertType(destTy);
-      if (t != v.getType())
-        cgf.getCIRGenModule().errorNYI("pointer qualification conversion");
-    }
-    return v;
-  }
+  case CK_NoOp:
+    return ce->changesVolatileQualification() ? emitLoadOfLValue(ce)
+                                              : Visit(subExpr);
   case CK_IntegralToPointer: {
     mlir::Type destCIRTy = cgf.convertType(destTy);
     mlir::Value src = Visit(const_cast<Expr *>(subExpr));
diff --git a/clang/test/CIR/CodeGen/cast-cxx20.cpp 
b/clang/test/CIR/CodeGen/cast-cxx20.cpp
index ebc2064dd0b69..802bcecafcb70 100644
--- a/clang/test/CIR/CodeGen/cast-cxx20.cpp
+++ b/clang/test/CIR/CodeGen/cast-cxx20.cpp
@@ -53,3 +53,22 @@ void cast3() {
   // LLVM: %[[TO_ARR_ALLOCA:.*]] = alloca ptr
   // LLVM: store ptr %[[ARR_ALLOCA]], ptr %[[TO_ARR_ALLOCA]]
 }
+
+void cast4() {
+  Arr4Ty* const *arrPP;
+  CArrNTy* const volatile *const constArrPP = arrPP;
+
+  // CIR-LABEL: cir.func {{.*}}@_Z5cast4v()
+  // CIR: %[[ARR_PP_ALLOCA:.*]] = cir.alloca 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>>, ["arrPP"]
+  // CIR: %[[CONST_ARR_ALLOCA:.*]] = cir.alloca 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 0>>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 0>>>>, ["constArrPP", init, const]
+  // CIR: %[[LOAD_ARR_PP:.*]] = cir.load align(8) %[[ARR_PP_ALLOCA]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>>, 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>
+  // CIR: %[[CONST_ARR_CAST:.*]] = cir.cast bitcast %[[CONST_ARR_ALLOCA]] : 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 0>>>> -> 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>>
+  // CIR: cir.store{{.*}} %[[LOAD_ARR_PP]], %[[CONST_ARR_CAST]] : 
!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>, 
!cir.ptr<!cir.ptr<!cir.ptr<!cir.array<!s32i x 4>>>>
+  //
+  // LLVM-LABEL: define {{.*}}@_Z5cast4v()
+  // LLVM: %[[ARR_PP_ALLOCA:.*]] = alloca ptr
+  // LLVM: %[[CONST_ARR_ALLOCA:.*]] = alloca ptr
+  // LLVM: %[[LOAD_ARR_PP:.*]] = load ptr, ptr %[[ARR_PP_ALLOCA]]
+  // LLVM: store ptr %[[LOAD_ARR_PP]], ptr %[[CONST_ARR_ALLOCA]]
+
+}

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

Reply via email to