Skip to content

Commit 69a5f2c

Browse files
committed
[CIR] [CodeGen] Handle NYI in CIRGenModule::tryEmitBaseDestructorAsAlias
1 parent 888f00c commit 69a5f2c

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3531,6 +3531,16 @@ class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []> :
35313531

35323532
bool isIndirect() { return !getCallee(); }
35333533
mlir::Value getIndirectCall();
3534+
3535+
void setArg(unsigned index, mlir::Value value) {
3536+
if (!isIndirect()) {
3537+
setOperand(index, value);
3538+
return;
3539+
}
3540+
3541+
// For indirect call, the operand list is shifted by one.
3542+
setOperand(index + 1, value);
3543+
}
35343544
}];
35353545

35363546
let hasCustomAssemblyFormat = 1;

clang/lib/CIR/CodeGen/CIRGenCXX.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ bool CIRGenModule::tryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
145145
// members with attribute "AlwaysInline" and expect no reference to
146146
// be generated. It is desirable to reenable this optimisation after
147147
// corresponding LLVM changes.
148-
llvm_unreachable("NYI");
148+
addReplacement(MangledName, Aliasee);
149+
return false;
149150
}
150151

151152
// If we have a weak, non-discardable alias (weak, weak_odr), like an
@@ -154,7 +155,8 @@ bool CIRGenModule::tryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
154155
// symbol reference from another TU. The other TU must also mark the
155156
// referenced symbol as weak, which we cannot rely on.
156157
if (cir::isWeakForLinker(Linkage) && getTriple().isOSBinFormatCOFF()) {
157-
llvm_unreachable("NYI");
158+
assert(false && "please sent a PR with a test and remove this.\n");
159+
return true;
158160
}
159161

160162
// If we don't have a definition for the destructor yet or the definition
@@ -168,8 +170,10 @@ bool CIRGenModule::tryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
168170
// different COMDATs in different TUs. Another option would be to
169171
// output the alias both for weak_odr and linkonce_odr, but that
170172
// requires explicit comdat support in the IL.
171-
if (cir::isWeakForLinker(TargetLinkage))
172-
llvm_unreachable("NYI");
173+
if (cir::isWeakForLinker(TargetLinkage)) {
174+
assert(false && "please sent a PR with a test and remove this.\n");
175+
return true;
176+
}
173177

174178
// Create the alias with no name.
175179
emitAliasForGlobal(MangledName, Entry, AliasDecl, Aliasee, Linkage);

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3193,6 +3193,39 @@ void CIRGenModule::addReplacement(StringRef Name, mlir::Operation *Op) {
31933193
Replacements[Name] = Op;
31943194
}
31953195

3196+
void CIRGenModule::replacePointerTypeArgs(cir::FuncOp OldF, cir::FuncOp NewF) {
3197+
auto optionalUseRange = OldF.getSymbolUses(theModule);
3198+
if (!optionalUseRange)
3199+
return;
3200+
3201+
for (auto U : *optionalUseRange) {
3202+
// FIXME: Handling TryCallOp here once they have the same base op.
3203+
auto Call = mlir::dyn_cast<cir::CallOp>(U.getUser());
3204+
if (!Call)
3205+
continue;
3206+
3207+
auto ArgOps = Call.getArgOps();
3208+
auto FuncArgTypes = NewF.getFunctionType().getInputs();
3209+
for (unsigned I = 0; I < FuncArgTypes.size(); I++) {
3210+
if (ArgOps[I].getType() == FuncArgTypes[I])
3211+
continue;
3212+
3213+
auto argPointerTy = mlir::dyn_cast<cir::PointerType>(ArgOps[I].getType());
3214+
auto funcArgPointerTy = mlir::dyn_cast<cir::PointerType>(FuncArgTypes[I]);
3215+
3216+
// If we can't solve it, leave it for the verifier to bail out.
3217+
if (!argPointerTy || !funcArgPointerTy)
3218+
continue;
3219+
3220+
mlir::OpBuilder::InsertionGuard guard(builder);
3221+
builder.setInsertionPoint(Call);
3222+
auto castedArg =
3223+
builder.createBitcast(Call.getLoc(), ArgOps[I], funcArgPointerTy);
3224+
Call.setArg(I, castedArg);
3225+
}
3226+
}
3227+
}
3228+
31963229
void CIRGenModule::applyReplacements() {
31973230
for (auto &I : Replacements) {
31983231
StringRef MangledName = I.first();
@@ -3205,6 +3238,10 @@ void CIRGenModule::applyReplacements() {
32053238
auto NewF = dyn_cast<cir::FuncOp>(Replacement);
32063239
assert(NewF && "not implemented");
32073240

3241+
// LLVM has opaque pointer but CIR not. So we may have to handle these
3242+
// different pointer types when performing replacement.
3243+
replacePointerTypeArgs(OldF, NewF);
3244+
32083245
// Replace old with new, but keep the old order.
32093246
if (OldF.replaceAllSymbolUses(NewF.getSymNameAttr(), theModule).failed())
32103247
llvm_unreachable("internal error, cannot RAUW symbol");

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,11 @@ class CIRGenModule : public CIRGenTypeCache {
871871
/// Call replaceAllUsesWith on all pairs in Replacements.
872872
void applyReplacements();
873873

874+
/// A helper function to replace all uses of OldF to NewF that replace
875+
/// the type of pointer arguments. This is not needed to tradtional
876+
/// pipeline since LLVM has opaque pointers but CIR not.
877+
void replacePointerTypeArgs(cir::FuncOp OldF, cir::FuncOp NewF);
878+
874879
void setNonAliasAttributes(GlobalDecl GD, mlir::Operation *GV);
875880
/// Map source language used to a CIR attribute.
876881
cir::SourceLanguage getCIRSourceLanguage();

clang/test/CIR/CodeGen/dtor-alias.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// FIXME: Remove of -clangir-disable-passes may trigger a memory safe bug in CIR internally during
2+
// lowering
3+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu \
4+
// RUN: -mconstructor-aliases -fclangir -emit-cir %s -o %t.cir \
5+
// RUN: -clangir-disable-passes -o %t.cir
6+
// RUN: FileCheck %s --input-file=%t.cir
7+
8+
namespace {
9+
struct A {
10+
~A() {}
11+
};
12+
13+
struct B : public A {};
14+
}
15+
16+
B x;
17+
18+
// CHECK: cir.call @_ZN12_GLOBAL__N_11AD2Ev({{.*}}) : (!cir.ptr<!ty_28anonymous_namespace293A3AA>) -> ()

0 commit comments

Comments
 (0)