-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CIR] Handle scalar DerivedToBase cast expressions #167370
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
Conversation
This adds handling in CIR's ScalarExprEmitter for CK_DerivedToBase cast expressions.
|
@llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) ChangesThis adds handling in CIR's ScalarExprEmitter for CK_DerivedToBase cast expressions. Full diff: https://github.com/llvm/llvm-project/pull/167370.diff 6 Files Affected:
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index af1ffffcf54c0..3f6fab0447445 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -294,6 +294,7 @@ struct MissingFeatures {
static bool opTBAA() { return false; }
static bool peepholeProtection() { return false; }
static bool pgoUse() { return false; }
+ static bool pointerAuthentication() { return false; }
static bool pointerOverflowSanitizer() { return false; }
static bool preservedAccessIndexRegion() { return false; }
static bool requiresCleanups() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 5eba5ba6c3df1..3f40cf0c0027a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1929,6 +1929,14 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
return builder.createIntToPtr(middleVal, destCIRTy);
}
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBase: {
+ // The EmitPointerWithAlignment path does this fine; just discard
+ // the alignment.
+ return cgf.getAsNaturalPointerTo(cgf.emitPointerWithAlignment(ce),
+ ce->getType()->getPointeeType());
+ }
+
case CK_Dynamic: {
Address v = cgf.emitPointerWithAlignment(subExpr);
const auto *dce = cast<CXXDynamicCastExpr>(ce);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index f879e580989f7..cab4a3d4d3b25 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -497,6 +497,12 @@ class CIRGenFunction : public CIRGenTypeCache {
VlaSizePair getVLASize(const VariableArrayType *type);
VlaSizePair getVLASize(QualType type);
+ Address getAsNaturalAddressOf(Address addr, QualType pointeeTy);
+
+ mlir::Value getAsNaturalPointerTo(Address addr, QualType pointeeType) {
+ return getAsNaturalAddressOf(addr, pointeeType).getBasePointer();
+ }
+
void finishFunction(SourceLocation endLoc);
/// Determine whether the given initializer is trivial in the sense
diff --git a/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp b/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp
new file mode 100644
index 0000000000000..20b0646fdab44
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp
@@ -0,0 +1,23 @@
+//===--- CIRGenPointerAuth.cpp - CIR generation for ptr auth --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains common routines relating to the emission of
+// pointer authentication operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenFunction.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+Address CIRGenFunction::getAsNaturalAddressOf(Address addr,
+ QualType pointeeTy) {
+ assert(!cir::MissingFeatures::pointerAuthentication());
+ return addr;
+}
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 7c31beacc5fb3..d3e2290ceea0b 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -35,6 +35,7 @@ add_clang_library(clangCIR
CIRGenOpenACC.cpp
CIRGenOpenACCClause.cpp
CIRGenOpenACCRecipe.cpp
+ CIRGenPointerAuth.cpp
CIRGenRecordLayoutBuilder.cpp
CIRGenStmt.cpp
CIRGenStmtOpenACC.cpp
diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp b/clang/test/CIR/CodeGen/derived-to-base.cpp
new file mode 100644
index 0000000000000..13acb47022c65
--- /dev/null
+++ b/clang/test/CIR/CodeGen/derived-to-base.cpp
@@ -0,0 +1,129 @@
+// 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 -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 -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+// TODO(cir): The constructors in this test case are only here because we don't
+// have support for zero-initialization of base classes yet. We should
+// fix that soon.
+
+struct Base {
+ Base();
+ void f();
+ int a;
+};
+
+struct Derived : Base {
+ Derived();
+ double b;
+};
+
+void f() {
+ Derived d;
+ d.f();
+}
+
+// CIR: cir.func {{.*}} @_Z1fv()
+// CIR: %[[D:.*]] = cir.alloca !rec_Derived, !cir.ptr<!rec_Derived>, ["d", init]
+// CIR: cir.call @_ZN7DerivedC1Ev(%[[D]]) : (!cir.ptr<!rec_Derived>) -> ()
+// CIR: %[[D_BASE:.*]] = cir.base_class_addr %[[D]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.call @_ZN4Base1fEv(%[[D_BASE]]) : (!cir.ptr<!rec_Base>) -> ()
+
+// LLVM: define {{.*}}void @_Z1fv()
+// LLVM: %[[D:.*]] = alloca %struct.Derived
+// LLVM: call void @_ZN7DerivedC1Ev(ptr %[[D]])
+// LLVM: call void @_ZN4Base1fEv(ptr %[[D]])
+
+// OGCG: define {{.*}}void @_Z1fv()
+// OGCG: %[[D:.*]] = alloca %struct.Derived
+// OGCG: call void @_ZN7DerivedC1Ev(ptr {{.*}} %[[D]])
+// OGCG: call void @_ZN4Base1fEv(ptr {{.*}} %[[D]])
+
+void useBase(Base *base);
+void callBaseUsingDerived(Derived *derived) {
+ useBase(derived);
+}
+
+
+// CIR: cir.func {{.*}} @_Z20callBaseUsingDerivedP7Derived(%[[DERIVED_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}})
+// CIR: %[[DERIVED_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["derived", init]
+// CIR: cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.call @_Z7useBaseP4Base(%[[DERIVED_BASE]]) : (!cir.ptr<!rec_Base>) -> ()
+
+// LLVM: define {{.*}} void @_Z20callBaseUsingDerivedP7Derived(ptr %[[DERIVED_ARG:.*]])
+// LLVM: %[[DERIVED_ADDR:.*]] = alloca ptr
+// LLVM: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// LLVM: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+// LLVM: call void @_Z7useBaseP4Base(ptr %[[DERIVED]])
+
+// OGCG: define {{.*}} void @_Z20callBaseUsingDerivedP7Derived(ptr {{.*}} %[[DERIVED_ARG:.*]])
+// OGCG: %[[DERIVED_ADDR:.*]] = alloca ptr
+// OGCG: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// OGCG: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+// OGCG: call void @_Z7useBaseP4Base(ptr {{.*}} %[[DERIVED]])
+
+Base *returnBaseFromDerived(Derived* derived) {
+ return derived;
+}
+
+// CIR: cir.func {{.*}} @_Z21returnBaseFromDerivedP7Derived(%[[DERIVED_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}}) -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["derived", init]
+// CIR: %[[BASE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>>, ["__retval"]
+// CIR: cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.store %[[DERIVED_BASE]], %[[BASE_ADDR]]
+// CIR: %[[BASE:.*]] = cir.load{{.*}} %[[BASE_ADDR]]
+// CIR: cir.return %[[BASE]] : !cir.ptr<!rec_Base>
+
+// LLVM: define {{.*}} ptr @_Z21returnBaseFromDerivedP7Derived(ptr %[[DERIVED_ARG:.*]])
+// LLVM: %[[DERIVED_ADDR:.*]] = alloca ptr
+// LLVM: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// LLVM: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+
+// OGCG: define {{.*}} ptr @_Z21returnBaseFromDerivedP7Derived(ptr {{.*}} %[[DERIVED_ARG:.*]])
+// OGCG: %[[DERIVED_ADDR:.*]] = alloca ptr
+// OGCG: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// OGCG: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+
+volatile Derived derivedObj;
+
+void test_volatile_store() {
+ derivedObj.a = 0;
+}
+
+// CIR: cir.func {{.*}} @_Z19test_volatile_storev()
+// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CIR: %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : !cir.ptr<!rec_Derived>
+// CIR: %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] {name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
+// CIR: cir.store volatile {{.*}} %[[ZERO]], %[[DERIVED_OBJ_A]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: define {{.*}} void @_Z19test_volatile_storev()
+// LLVM: store volatile i32 0, ptr @derivedObj
+
+// OGCG: define {{.*}} void @_Z19test_volatile_storev()
+// OGCG: store volatile i32 0, ptr @derivedObj
+
+void test_volatile_load() {
+ [[maybe_unused]] int val = derivedObj.a;
+}
+
+// CIR: cir.func {{.*}} @_Z18test_volatile_loadv()
+// CIR: %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : !cir.ptr<!rec_Derived>
+// CIR: %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] {name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
+// CIR: %[[VAL:.*]] = cir.load volatile {{.*}} %[[DERIVED_OBJ_A]] : !cir.ptr<!s32i>, !s32i
+
+// LLVM: define {{.*}} void @_Z18test_volatile_loadv()
+// LLVM: %[[VAL_ADDR:.*]] = alloca i32
+// LLVM: %[[DERIVED_OBJ:.*]] = load volatile i32, ptr @derivedObj
+
+// OGCG: define {{.*}} void @_Z18test_volatile_loadv()
+// OGCG: %[[VAL_ADDR:.*]] = alloca i32
+// OGCG: %[[DERIVED_OBJ:.*]] = load volatile i32, ptr @derivedObj
+// OGCG: store i32 %[[DERIVED_OBJ]], ptr %[[VAL_ADDR]]
|
|
@llvm/pr-subscribers-clang Author: Andy Kaylor (andykaylor) ChangesThis adds handling in CIR's ScalarExprEmitter for CK_DerivedToBase cast expressions. Full diff: https://github.com/llvm/llvm-project/pull/167370.diff 6 Files Affected:
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index af1ffffcf54c0..3f6fab0447445 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -294,6 +294,7 @@ struct MissingFeatures {
static bool opTBAA() { return false; }
static bool peepholeProtection() { return false; }
static bool pgoUse() { return false; }
+ static bool pointerAuthentication() { return false; }
static bool pointerOverflowSanitizer() { return false; }
static bool preservedAccessIndexRegion() { return false; }
static bool requiresCleanups() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 5eba5ba6c3df1..3f40cf0c0027a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1929,6 +1929,14 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
return builder.createIntToPtr(middleVal, destCIRTy);
}
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBase: {
+ // The EmitPointerWithAlignment path does this fine; just discard
+ // the alignment.
+ return cgf.getAsNaturalPointerTo(cgf.emitPointerWithAlignment(ce),
+ ce->getType()->getPointeeType());
+ }
+
case CK_Dynamic: {
Address v = cgf.emitPointerWithAlignment(subExpr);
const auto *dce = cast<CXXDynamicCastExpr>(ce);
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index f879e580989f7..cab4a3d4d3b25 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -497,6 +497,12 @@ class CIRGenFunction : public CIRGenTypeCache {
VlaSizePair getVLASize(const VariableArrayType *type);
VlaSizePair getVLASize(QualType type);
+ Address getAsNaturalAddressOf(Address addr, QualType pointeeTy);
+
+ mlir::Value getAsNaturalPointerTo(Address addr, QualType pointeeType) {
+ return getAsNaturalAddressOf(addr, pointeeType).getBasePointer();
+ }
+
void finishFunction(SourceLocation endLoc);
/// Determine whether the given initializer is trivial in the sense
diff --git a/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp b/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp
new file mode 100644
index 0000000000000..20b0646fdab44
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp
@@ -0,0 +1,23 @@
+//===--- CIRGenPointerAuth.cpp - CIR generation for ptr auth --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains common routines relating to the emission of
+// pointer authentication operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenFunction.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+Address CIRGenFunction::getAsNaturalAddressOf(Address addr,
+ QualType pointeeTy) {
+ assert(!cir::MissingFeatures::pointerAuthentication());
+ return addr;
+}
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 7c31beacc5fb3..d3e2290ceea0b 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -35,6 +35,7 @@ add_clang_library(clangCIR
CIRGenOpenACC.cpp
CIRGenOpenACCClause.cpp
CIRGenOpenACCRecipe.cpp
+ CIRGenPointerAuth.cpp
CIRGenRecordLayoutBuilder.cpp
CIRGenStmt.cpp
CIRGenStmtOpenACC.cpp
diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp b/clang/test/CIR/CodeGen/derived-to-base.cpp
new file mode 100644
index 0000000000000..13acb47022c65
--- /dev/null
+++ b/clang/test/CIR/CodeGen/derived-to-base.cpp
@@ -0,0 +1,129 @@
+// 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 -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 -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+// TODO(cir): The constructors in this test case are only here because we don't
+// have support for zero-initialization of base classes yet. We should
+// fix that soon.
+
+struct Base {
+ Base();
+ void f();
+ int a;
+};
+
+struct Derived : Base {
+ Derived();
+ double b;
+};
+
+void f() {
+ Derived d;
+ d.f();
+}
+
+// CIR: cir.func {{.*}} @_Z1fv()
+// CIR: %[[D:.*]] = cir.alloca !rec_Derived, !cir.ptr<!rec_Derived>, ["d", init]
+// CIR: cir.call @_ZN7DerivedC1Ev(%[[D]]) : (!cir.ptr<!rec_Derived>) -> ()
+// CIR: %[[D_BASE:.*]] = cir.base_class_addr %[[D]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.call @_ZN4Base1fEv(%[[D_BASE]]) : (!cir.ptr<!rec_Base>) -> ()
+
+// LLVM: define {{.*}}void @_Z1fv()
+// LLVM: %[[D:.*]] = alloca %struct.Derived
+// LLVM: call void @_ZN7DerivedC1Ev(ptr %[[D]])
+// LLVM: call void @_ZN4Base1fEv(ptr %[[D]])
+
+// OGCG: define {{.*}}void @_Z1fv()
+// OGCG: %[[D:.*]] = alloca %struct.Derived
+// OGCG: call void @_ZN7DerivedC1Ev(ptr {{.*}} %[[D]])
+// OGCG: call void @_ZN4Base1fEv(ptr {{.*}} %[[D]])
+
+void useBase(Base *base);
+void callBaseUsingDerived(Derived *derived) {
+ useBase(derived);
+}
+
+
+// CIR: cir.func {{.*}} @_Z20callBaseUsingDerivedP7Derived(%[[DERIVED_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}})
+// CIR: %[[DERIVED_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["derived", init]
+// CIR: cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.call @_Z7useBaseP4Base(%[[DERIVED_BASE]]) : (!cir.ptr<!rec_Base>) -> ()
+
+// LLVM: define {{.*}} void @_Z20callBaseUsingDerivedP7Derived(ptr %[[DERIVED_ARG:.*]])
+// LLVM: %[[DERIVED_ADDR:.*]] = alloca ptr
+// LLVM: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// LLVM: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+// LLVM: call void @_Z7useBaseP4Base(ptr %[[DERIVED]])
+
+// OGCG: define {{.*}} void @_Z20callBaseUsingDerivedP7Derived(ptr {{.*}} %[[DERIVED_ARG:.*]])
+// OGCG: %[[DERIVED_ADDR:.*]] = alloca ptr
+// OGCG: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// OGCG: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+// OGCG: call void @_Z7useBaseP4Base(ptr {{.*}} %[[DERIVED]])
+
+Base *returnBaseFromDerived(Derived* derived) {
+ return derived;
+}
+
+// CIR: cir.func {{.*}} @_Z21returnBaseFromDerivedP7Derived(%[[DERIVED_ARG:.*]]: !cir.ptr<!rec_Derived> {{.*}}) -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["derived", init]
+// CIR: %[[BASE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Base>, !cir.ptr<!cir.ptr<!rec_Base>>, ["__retval"]
+// CIR: cir.store %[[DERIVED_ARG]], %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED:.*]] = cir.load{{.*}} %[[DERIVED_ADDR]]
+// CIR: %[[DERIVED_BASE:.*]] = cir.base_class_addr %[[DERIVED]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: cir.store %[[DERIVED_BASE]], %[[BASE_ADDR]]
+// CIR: %[[BASE:.*]] = cir.load{{.*}} %[[BASE_ADDR]]
+// CIR: cir.return %[[BASE]] : !cir.ptr<!rec_Base>
+
+// LLVM: define {{.*}} ptr @_Z21returnBaseFromDerivedP7Derived(ptr %[[DERIVED_ARG:.*]])
+// LLVM: %[[DERIVED_ADDR:.*]] = alloca ptr
+// LLVM: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// LLVM: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+
+// OGCG: define {{.*}} ptr @_Z21returnBaseFromDerivedP7Derived(ptr {{.*}} %[[DERIVED_ARG:.*]])
+// OGCG: %[[DERIVED_ADDR:.*]] = alloca ptr
+// OGCG: store ptr %[[DERIVED_ARG]], ptr %[[DERIVED_ADDR]]
+// OGCG: %[[DERIVED:.*]] = load ptr, ptr %[[DERIVED_ADDR]]
+
+volatile Derived derivedObj;
+
+void test_volatile_store() {
+ derivedObj.a = 0;
+}
+
+// CIR: cir.func {{.*}} @_Z19test_volatile_storev()
+// CIR: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i
+// CIR: %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : !cir.ptr<!rec_Derived>
+// CIR: %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] {name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
+// CIR: cir.store volatile {{.*}} %[[ZERO]], %[[DERIVED_OBJ_A]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: define {{.*}} void @_Z19test_volatile_storev()
+// LLVM: store volatile i32 0, ptr @derivedObj
+
+// OGCG: define {{.*}} void @_Z19test_volatile_storev()
+// OGCG: store volatile i32 0, ptr @derivedObj
+
+void test_volatile_load() {
+ [[maybe_unused]] int val = derivedObj.a;
+}
+
+// CIR: cir.func {{.*}} @_Z18test_volatile_loadv()
+// CIR: %[[DERIVED_OBJ:.*]] = cir.get_global @derivedObj : !cir.ptr<!rec_Derived>
+// CIR: %[[DERIVED_OBJ_BASE:.*]] = cir.base_class_addr %[[DERIVED_OBJ]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>
+// CIR: %[[DERIVED_OBJ_A:.*]] = cir.get_member %[[DERIVED_OBJ_BASE]][0] {name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>
+// CIR: %[[VAL:.*]] = cir.load volatile {{.*}} %[[DERIVED_OBJ_A]] : !cir.ptr<!s32i>, !s32i
+
+// LLVM: define {{.*}} void @_Z18test_volatile_loadv()
+// LLVM: %[[VAL_ADDR:.*]] = alloca i32
+// LLVM: %[[DERIVED_OBJ:.*]] = load volatile i32, ptr @derivedObj
+
+// OGCG: define {{.*}} void @_Z18test_volatile_loadv()
+// OGCG: %[[VAL_ADDR:.*]] = alloca i32
+// OGCG: %[[DERIVED_OBJ:.*]] = load volatile i32, ptr @derivedObj
+// OGCG: store i32 %[[DERIVED_OBJ]], ptr %[[VAL_ADDR]]
|
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/42158 Here is the relevant piece of the build log for the reference |
This adds handling in CIR's ScalarExprEmitter for CK_DerivedToBase cast expressions.
This adds handling in CIR's ScalarExprEmitter for CK_DerivedToBase cast expressions.