Skip to content

Commit b56869f

Browse files
ChuanqiXu9lanza
authored andcommitted
[CIR][CIRGen] Handle NYI in CIRGenModule::tryEmitBaseDestructorAsAlias (#1180)
This removes some NYI in CIRGenModule::tryEmitBaseDestructorAsAlias and similar to #1179, use `assert(false)` to tell devs to add test. It is slightly verbose due to the difference between LLVM and CIR's type system. LLVM's pointer are opaque types while CIR's pointer are typed. So we need to handle these pointers when transforming the generated cir.
1 parent 41295de commit b56869f

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

Diff for: clang/include/clang/CIR/Dialect/IR/CIROps.td

+10
Original file line numberDiff line numberDiff line change
@@ -3594,6 +3594,16 @@ class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []> :
35943594

35953595
bool isIndirect() { return !getCallee(); }
35963596
mlir::Value getIndirectCall();
3597+
3598+
void setArg(unsigned index, mlir::Value value) {
3599+
if (!isIndirect()) {
3600+
setOperand(index, value);
3601+
return;
3602+
}
3603+
3604+
// For indirect call, the operand list is shifted by one.
3605+
setOperand(index + 1, value);
3606+
}
35973607
}];
35983608

35993609
let hasCustomAssemblyFormat = 1;

Diff for: clang/lib/CIR/CodeGen/CIRGenCXX.cpp

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

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

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

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

Diff for: clang/lib/CIR/CodeGen/CIRGenModule.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -3493,6 +3493,39 @@ void CIRGenModule::addReplacement(StringRef Name, mlir::Operation *Op) {
34933493
Replacements[Name] = Op;
34943494
}
34953495

3496+
void CIRGenModule::replacePointerTypeArgs(cir::FuncOp OldF, cir::FuncOp NewF) {
3497+
auto optionalUseRange = OldF.getSymbolUses(theModule);
3498+
if (!optionalUseRange)
3499+
return;
3500+
3501+
for (auto U : *optionalUseRange) {
3502+
// CallTryOp only shows up after FlattenCFG.
3503+
auto Call = mlir::dyn_cast<cir::CallOp>(U.getUser());
3504+
if (!Call)
3505+
continue;
3506+
3507+
auto ArgOps = Call.getArgOps();
3508+
auto FuncArgTypes = NewF.getFunctionType().getInputs();
3509+
for (unsigned I = 0; I < FuncArgTypes.size(); I++) {
3510+
if (ArgOps[I].getType() == FuncArgTypes[I])
3511+
continue;
3512+
3513+
auto argPointerTy = mlir::dyn_cast<cir::PointerType>(ArgOps[I].getType());
3514+
auto funcArgPointerTy = mlir::dyn_cast<cir::PointerType>(FuncArgTypes[I]);
3515+
3516+
// If we can't solve it, leave it for the verifier to bail out.
3517+
if (!argPointerTy || !funcArgPointerTy)
3518+
continue;
3519+
3520+
mlir::OpBuilder::InsertionGuard guard(builder);
3521+
builder.setInsertionPoint(Call);
3522+
auto castedArg =
3523+
builder.createBitcast(Call.getLoc(), ArgOps[I], funcArgPointerTy);
3524+
Call.setArg(I, castedArg);
3525+
}
3526+
}
3527+
}
3528+
34963529
void CIRGenModule::applyReplacements() {
34973530
for (auto &I : Replacements) {
34983531
StringRef MangledName = I.first();
@@ -3505,6 +3538,10 @@ void CIRGenModule::applyReplacements() {
35053538
auto NewF = dyn_cast<cir::FuncOp>(Replacement);
35063539
assert(NewF && "not implemented");
35073540

3541+
// LLVM has opaque pointer but CIR not. So we may have to handle these
3542+
// different pointer types when performing replacement.
3543+
replacePointerTypeArgs(OldF, NewF);
3544+
35083545
// Replace old with new, but keep the old order.
35093546
if (OldF.replaceAllSymbolUses(NewF.getSymNameAttr(), theModule).failed())
35103547
llvm_unreachable("internal error, cannot RAUW symbol");

Diff for: clang/lib/CIR/CodeGen/CIRGenModule.h

+5
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,11 @@ class CIRGenModule : public CIRGenTypeCache {
860860
/// Call replaceAllUsesWith on all pairs in Replacements.
861861
void applyReplacements();
862862

863+
/// A helper function to replace all uses of OldF to NewF that replace
864+
/// the type of pointer arguments. This is not needed to tradtional
865+
/// pipeline since LLVM has opaque pointers but CIR not.
866+
void replacePointerTypeArgs(cir::FuncOp OldF, cir::FuncOp NewF);
867+
863868
void setNonAliasAttributes(GlobalDecl GD, mlir::Operation *GV);
864869
/// Map source language used to a CIR attribute.
865870
cir::SourceLanguage getCIRSourceLanguage();

Diff for: clang/test/CIR/CodeGen/dtor-alias.cpp

+18
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)