https://github.com/erichkeane updated https://github.com/llvm/llvm-project/pull/191485
>From f670a4f78a0515ad0b4a1558f5d14ad58bc94394 Mon Sep 17 00:00:00 2001 From: erichkeane <[email protected]> Date: Fri, 10 Apr 2026 10:44:47 -0700 Subject: [PATCH 1/2] [[CIR]] Implement 'to-union' cast. This ends up being pretty trivial/can only really happen in 2 ways, the only useful way is via an extension. This patch implements this. This doesn't really affect anything as it is a pretty rarely used feature and thus doesn't appear in the test suite I've seen, but I saw it while investigating something else. --- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 5 ++- clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 13 ++++++ clang/test/CIR/CodeGen/casts.c | 44 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 clang/test/CIR/CodeGen/casts.c diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index a306cc68dff8e..cd3e4671ac106 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -1498,9 +1498,11 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { } // These are never l-values; just use the aggregate emission code. + case CK_ToUnion: + return emitAggExprToLValue(e); + case CK_NonAtomicToAtomic: case CK_AtomicToNonAtomic: - case CK_ToUnion: case CK_ObjCObjectLValueCast: case CK_VectorSplat: case CK_ConstructorConversion: @@ -1514,6 +1516,7 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { return {}; } + case CK_AddressSpaceConversion: { LValue lv = emitLValue(e->getSubExpr()); QualType destTy = getContext().getPointerType(e->getType()); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index ffce8a6bf86a7..c5c30bb5e8cea 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -273,6 +273,19 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { "Implicit cast types must be compatible"); Visit(e->getSubExpr()); break; + case CK_ToUnion: { + if (dest.isIgnored()) { + cgf.emitAnyExpr(e->getSubExpr(), AggValueSlot::ignored(), + /*ignoreResult=*/true); + break; + } + QualType ty = e->getSubExpr()->getType(); + Address castPtr = dest.getAddress().withElementType(cgf.getBuilder(), + cgf.convertType(ty)); + emitInitializationToLValue(e->getSubExpr(), + cgf.makeAddrLValue(castPtr, ty)); + break; + } default: cgf.cgm.errorNYI(e->getSourceRange(), std::string("AggExprEmitter: VisitCastExpr: ") + diff --git a/clang/test/CIR/CodeGen/casts.c b/clang/test/CIR/CodeGen/casts.c new file mode 100644 index 0000000000000..cce29c49d2039 --- /dev/null +++ b/clang/test/CIR/CodeGen/casts.c @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -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-cir.ll %s -check-prefix=LLVM + +union Union { int i; float f; }; + +float getF(); + +void toUnion() { + // CIR-LABEL: toUnion() + // LLVM-LABEL: toUnion() + // + (void)(union Union) getF(); + // CIR: %[[F_FUNC:.*]] = cir.get_global @getF : !cir.ptr<!cir.func<(...) -> !cir.float>> + // CIR: %[[F_CAST:.*]] = cir.cast bitcast %[[F_FUNC]] : !cir.ptr<!cir.func<(...) -> !cir.float>> -> !cir.ptr<!cir.func<() -> !cir.float>> + // CIR: cir.call %[[F_CAST:.*]]() : (!cir.ptr<!cir.func<() -> !cir.float>>) -> !cir.float + // CIR: cir.return + + // LLVM: call float @getF() + // LLVM: ret void +} + +// GCC assign-from-cast extension: +union Union toUnionAssign() { + // CIR-LABEL: toUnionAssign() + // LLVM-LABEL: toUnionAssign() + // + // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !rec_Union, !cir.ptr<!rec_Union>, ["__retval"] + // LLVM: %[[RET_ALLOCA:.*]] = alloca %union.Union + union Union u; + u = (union Union)42; + // CIR: %[[UNION_TO_INT:.*]] = cir.cast bitcast %[[RET_ALLOCA]] : !cir.ptr<!rec_Union> -> !cir.ptr<!s32i> + // CIR: %[[INT42:.*]] = cir.const #cir.int<42> + // CIR: cir.store align(4) %[[INT42]], %[[UNION_TO_INT]] : !s32i, !cir.ptr<!s32i> + // LLVM: store i32 42, ptr %[[RET_ALLOCA]] + return u; + // CIR: %[[LOAD:.*]] = cir.load %[[RET_ALLOCA]] : !cir.ptr<!rec_Union>, !rec_Union + // CIR: cir.return %[[LOAD]] + // LLVM: %[[LOAD:.*]] = load %union.Union, ptr %[[RET_ALLOCA]] + // LLVM: ret %union.Union %[[LOAD]] +} >From f6eb8aca9b5d831f4a334ccf4d884dc8ee42ca46 Mon Sep 17 00:00:00 2001 From: erichkeane <[email protected]> Date: Mon, 13 Apr 2026 05:59:52 -0700 Subject: [PATCH 2/2] Move test --- clang/test/CIR/CodeGen/{casts.c => cast.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/test/CIR/CodeGen/{casts.c => cast.c} (100%) diff --git a/clang/test/CIR/CodeGen/casts.c b/clang/test/CIR/CodeGen/cast.c similarity index 100% rename from clang/test/CIR/CodeGen/casts.c rename to clang/test/CIR/CodeGen/cast.c _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
