-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[CIR] Implement CK_LValueToRValueBitCast for ComplexType #150296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CIR] Implement CK_LValueToRValueBitCast for ComplexType #150296
Conversation
@llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesThis change adds support for CK_LValueToRValueBitCast for ComplexType Full diff: https://github.com/llvm/llvm-project/pull/150296.diff 2 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index d52da0cb32c53..7f2e2ce311846 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -194,8 +194,12 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
}
case CK_LValueToRValueBitCast: {
- cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueToRValueBitCast");
- return {};
+ LValue sourceLVal = cgf.emitLValue(op);
+ Address addr = sourceLVal.getAddress().withElementType(
+ builder, cgf.convertTypeForMem(destTy));
+ LValue destLV = cgf.makeAddrLValue(addr, destTy);
+ assert(!cir::MissingFeatures::opTBAA());
+ return emitLoadOfLValue(destLV, op->getExprLoc());
}
case CK_BitCast:
diff --git a/clang/test/CIR/CodeGen/complex-cast.cpp b/clang/test/CIR/CodeGen/complex-cast.cpp
index 94f47e4730cc2..a5ae21e82b7c6 100644
--- a/clang/test/CIR/CodeGen/complex-cast.cpp
+++ b/clang/test/CIR/CodeGen/complex-cast.cpp
@@ -326,3 +326,28 @@ void complex_to_complex_cast() {
// OGCG: store i32 %[[REAL_INT_CAST]], ptr {{.*}}, align 4
// OGCG: store i32 %[[IMAG_INT_CAST]], ptr getelementptr inbounds nuw ({ i32, i32 }, ptr {{.*}}, i32 0, i32 1), align 4
+
+void lvalue_to_rvalue_bitcast() {
+ void *a;
+ int _Complex b = __builtin_bit_cast(int _Complex, a);
+}
+
+// CIR-BEFORE: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.complex<!s32i>>
+
+// CIR-AFTER: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.complex<!s32i>>
+
+// LLVM: %[[PTR_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM: %[[COMPLEX_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
+// LLVM: %[[PTR_TO_COMPLEX:.*]] = load { i32, i32 }, ptr %[[PTR_ADDR]], align 8
+// LLVM: store { i32, i32 } %[[PTR_TO_COMPLEX]], ptr %[[COMPLEX_ADDR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
+// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 4
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 8
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 1
+// OGCG: store i32 %[[A_REAL]], ptr %[[B_REAL_PTR]], align 4
+// OGCG: store i32 %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 4
|
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesThis change adds support for CK_LValueToRValueBitCast for ComplexType Full diff: https://github.com/llvm/llvm-project/pull/150296.diff 2 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index d52da0cb32c53..7f2e2ce311846 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -194,8 +194,12 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
}
case CK_LValueToRValueBitCast: {
- cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueToRValueBitCast");
- return {};
+ LValue sourceLVal = cgf.emitLValue(op);
+ Address addr = sourceLVal.getAddress().withElementType(
+ builder, cgf.convertTypeForMem(destTy));
+ LValue destLV = cgf.makeAddrLValue(addr, destTy);
+ assert(!cir::MissingFeatures::opTBAA());
+ return emitLoadOfLValue(destLV, op->getExprLoc());
}
case CK_BitCast:
diff --git a/clang/test/CIR/CodeGen/complex-cast.cpp b/clang/test/CIR/CodeGen/complex-cast.cpp
index 94f47e4730cc2..a5ae21e82b7c6 100644
--- a/clang/test/CIR/CodeGen/complex-cast.cpp
+++ b/clang/test/CIR/CodeGen/complex-cast.cpp
@@ -326,3 +326,28 @@ void complex_to_complex_cast() {
// OGCG: store i32 %[[REAL_INT_CAST]], ptr {{.*}}, align 4
// OGCG: store i32 %[[IMAG_INT_CAST]], ptr getelementptr inbounds nuw ({ i32, i32 }, ptr {{.*}}, i32 0, i32 1), align 4
+
+void lvalue_to_rvalue_bitcast() {
+ void *a;
+ int _Complex b = __builtin_bit_cast(int _Complex, a);
+}
+
+// CIR-BEFORE: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.complex<!s32i>>
+
+// CIR-AFTER: %{{.*}} = cir.cast(bitcast, %{{.*}} : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!cir.complex<!s32i>>
+
+// LLVM: %[[PTR_ADDR:.*]] = alloca ptr, i64 1, align 8
+// LLVM: %[[COMPLEX_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
+// LLVM: %[[PTR_TO_COMPLEX:.*]] = load { i32, i32 }, ptr %[[PTR_ADDR]], align 8
+// LLVM: store { i32, i32 } %[[PTR_TO_COMPLEX]], ptr %[[COMPLEX_ADDR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
+// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 4
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 8
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[B_ADDR]], i32 0, i32 1
+// OGCG: store i32 %[[A_REAL]], ptr %[[B_REAL_PTR]], align 4
+// OGCG: store i32 %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 4
|
void lvalue_to_rvalue_bitcast() { | ||
void *a; | ||
int _Complex b = __builtin_bit_cast(int _Complex, a); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void lvalue_to_rvalue_bitcast() { | |
void *a; | |
int _Complex b = __builtin_bit_cast(int _Complex, a); | |
} | |
struct CX { | |
double real; | |
double imag; | |
}; | |
void lvalue_to_rvalue_bitcast() { | |
CX a; | |
double _Complex b = __builtin_bit_cast(double _Complex, b); | |
} |
I think the test as you had it is UB, even though it will pass. I think my suggested alternative is not UB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This change adds support for CK_LValueToRValueBitCast for ComplexType
#141365