Skip to content

Commit c455da4

Browse files
authored
Merge branch 'main' into complex_real_op_rvalue
2 parents b58da86 + 34c12ae commit c455da4

18 files changed

+361
-90
lines changed

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

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,29 +2962,16 @@ def CIR_GetMemberOp : CIR_Op<"get_member"> {
29622962
let arguments = (ins
29632963
Arg<CIR_PointerType, "the address to load from", [MemRead]>:$addr,
29642964
StrAttr:$name,
2965-
IndexAttr:$index_attr);
2965+
I64Attr:$index);
29662966

29672967
let results = (outs Res<CIR_PointerType, "">:$result);
29682968

29692969
let assemblyFormat = [{
2970-
$addr `[` $index_attr `]` attr-dict
2970+
$addr `[` $index `]` attr-dict
29712971
`:` qualified(type($addr)) `->` qualified(type($result))
29722972
}];
29732973

2974-
let builders = [
2975-
OpBuilder<(ins "mlir::Type":$type,
2976-
"mlir::Value":$value,
2977-
"llvm::StringRef":$name,
2978-
"unsigned":$index),
2979-
[{
2980-
mlir::APInt fieldIdx(64, index);
2981-
build($_builder, $_state, type, value, name, fieldIdx);
2982-
}]>
2983-
];
2984-
29852974
let extraClassDeclaration = [{
2986-
/// Return the index of the record member being accessed.
2987-
uint64_t getIndex() { return getIndexAttr().getZExtValue(); }
29882975

29892976
/// Return the record type pointed by the base pointer.
29902977
cir::PointerType getAddrTy() { return getAddr().getType(); }

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ static mlir::Value emitX86ExpandLoad(CIRGenFunction &cgf,
134134
.getResult();
135135
}
136136

137+
static mlir::Value emitX86CompressStore(CIRGenFunction &cgf,
138+
ArrayRef<mlir::Value> ops,
139+
mlir::Location loc) {
140+
auto resultTy = cast<cir::VectorType>(ops[1].getType());
141+
mlir::Value ptr = ops[0];
142+
143+
mlir::Value maskVec = getMaskVecValue(cgf, ops[2], resultTy.getSize(), loc);
144+
145+
return cgf.getBuilder()
146+
.create<cir::LLVMIntrinsicCallOp>(
147+
loc, cgf.getBuilder().getStringAttr("masked.compressstore"),
148+
cgf.getBuilder().getVoidTy(), mlir::ValueRange{ops[1], ptr, maskVec})
149+
.getResult();
150+
}
151+
137152
static mlir::Value emitX86SExtMask(CIRGenFunction &cgf, mlir::Value op,
138153
mlir::Type dstTy, mlir::Location loc) {
139154
unsigned numberOfElements = cast<cir::VectorType>(dstTy).getSize();
@@ -645,7 +660,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
645660
case X86::BI__builtin_ia32_compressstoreqi128_mask:
646661
case X86::BI__builtin_ia32_compressstoreqi256_mask:
647662
case X86::BI__builtin_ia32_compressstoreqi512_mask:
648-
llvm_unreachable("compress*_mask NYI");
663+
return emitX86CompressStore(*this, Ops, getLoc(E->getExprLoc()));
649664

650665
case X86::BI__builtin_ia32_expanddf128_mask:
651666
case X86::BI__builtin_ia32_expanddf256_mask:

clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ bool CIRGenCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
8686
return true;
8787
}
8888

89+
mlir::TypedAttr CIRGenCXXABI::emitNullMemberPointer(clang::QualType T) {
90+
llvm_unreachable("NYI");
91+
}
92+
8993
CharUnits CIRGenCXXABI::getArrayCookieSize(const CXXNewExpr *E) {
9094
if (!requiresArrayCookie(E))
9195
return CharUnits::Zero();

clang/lib/CIR/CodeGen/CIRGenCXXABI.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ class CIRGenCXXABI {
292292
return true;
293293
}
294294

295+
/// Create a null member pointer of the given type.
296+
virtual mlir::TypedAttr emitNullMemberPointer(clang::QualType T);
297+
295298
/// Gets the offsets of all the virtual base pointers in a given class.
296299
virtual std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD);
297300

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,8 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *E) {
10561056
cir::GlobalOp var = CGM.getOrCreateStaticVarDecl(
10571057
*VD, CGM.getCIRLinkageVarDefinition(VD, /*IsConstant=*/false));
10581058
auto getGlobalOp = builder.createGetGlobal(var);
1059-
auto actualElemTy = llvm::cast<cir::PointerType>(getGlobalOp.getType()).getPointee();
1059+
auto actualElemTy =
1060+
llvm::cast<cir::PointerType>(getGlobalOp.getType()).getPointee();
10601061
addr = Address(getGlobalOp, actualElemTy, getContext().getDeclAlign(VD));
10611062
} else {
10621063
llvm_unreachable("DeclRefExpr for decl not entered in LocalDeclMap?");
@@ -2017,7 +2018,15 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *E) {
20172018
assert(0 && "NYI");
20182019
}
20192020
case CK_LValueBitCast: {
2020-
assert(0 && "NYI");
2021+
// This must be a reinterpret_cast (or c-style equivalent).
2022+
const auto *ce = cast<ExplicitCastExpr>(E);
2023+
2024+
CGM.emitExplicitCastExprType(ce, this);
2025+
LValue LV = emitLValue(E->getSubExpr());
2026+
Address V = LV.getAddress().withElementType(
2027+
builder, convertTypeForMem(ce->getTypeAsWritten()->getPointeeType()));
2028+
2029+
return makeAddrLValue(V, E->getType(), LV.getBaseInfo(), LV.getTBAAInfo());
20212030
}
20222031
case CK_AddressSpaceConversion: {
20232032
LValue LV = emitLValue(E->getSubExpr());

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,24 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
310310
}
311311

312312
mlir::Value
313-
VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO) {
314-
llvm_unreachable("NYI");
313+
VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
314+
mlir::Value condValue = Visit(E->getCond());
315+
mlir::Location loc = CGF.getLoc(E->getSourceRange());
316+
317+
return Builder
318+
.create<cir::TernaryOp>(
319+
loc, condValue,
320+
/*thenBuilder=*/
321+
[&](mlir::OpBuilder &b, mlir::Location loc) {
322+
mlir::Value trueValue = Visit(E->getTrueExpr());
323+
b.create<cir::YieldOp>(loc, trueValue);
324+
},
325+
/*elseBuilder=*/
326+
[&](mlir::OpBuilder &b, mlir::Location loc) {
327+
mlir::Value falseValue = Visit(E->getFalseExpr());
328+
b.create<cir::YieldOp>(loc, falseValue);
329+
})
330+
.getResult();
315331
}
316332

317333
mlir::Value VisitChooseExpr(ChooseExpr *CE) {
@@ -428,8 +444,13 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind CK, Expr *Op,
428444
case CK_UserDefinedConversion:
429445
llvm_unreachable("NYI");
430446

431-
case CK_LValueBitCast:
432-
llvm_unreachable("NYI");
447+
case CK_LValueBitCast: {
448+
LValue origLV = CGF.emitLValue(Op);
449+
Address addr =
450+
origLV.getAddress().withElementType(Builder, CGF.convertType(DestTy));
451+
LValue destLV = CGF.makeAddrLValue(addr, DestTy);
452+
return emitLoadOfLValue(destLV, Op->getExprLoc());
453+
}
433454

434455
case CK_LValueToRValueBitCast: {
435456
LValue SourceLVal = CGF.emitLValue(Op);

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,20 +1733,21 @@ static mlir::TypedAttr emitNullConstant(CIRGenModule &CGM, const RecordDecl *rd,
17331733
}
17341734

17351735
// Fill in all the fields.
1736-
for (const auto *Field : rd->fields()) {
1736+
for (const auto *field : rd->fields()) {
17371737
// Fill in non-bitfields. (Bitfields always use a zero pattern, which we
17381738
// will fill in later.)
1739-
if (!Field->isBitField() &&
1740-
!isEmptyFieldForLayout(CGM.getASTContext(), Field)) {
1741-
llvm_unreachable("NYI");
1739+
if (!field->isBitField() &&
1740+
!isEmptyFieldForLayout(CGM.getASTContext(), field)) {
1741+
unsigned fieldIndex = layout.getCIRFieldNo(field);
1742+
elements[fieldIndex] = CGM.emitNullConstant(field->getType());
17421743
}
17431744

17441745
// For unions, stop after the first named field.
17451746
if (rd->isUnion()) {
1746-
if (Field->getIdentifier())
1747+
if (field->getIdentifier())
17471748
break;
1748-
if (const auto *FieldRD = Field->getType()->getAsRecordDecl())
1749-
if (FieldRD->findFirstNamedDataMember())
1749+
if (const auto *fieldRD = field->getType()->getAsRecordDecl())
1750+
if (fieldRD->findFirstNamedDataMember())
17501751
break;
17511752
}
17521753
}
@@ -1780,27 +1781,8 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
17801781
if (const CXXConstructExpr *E =
17811782
dyn_cast_or_null<CXXConstructExpr>(D.getInit())) {
17821783
const CXXConstructorDecl *CD = E->getConstructor();
1783-
// FIXME: we should probably model this more closely to C++ than
1784-
// just emitting a global with zero init (mimic what we do for trivial
1785-
// assignments and whatnots). Since this is for globals shouldn't
1786-
// be a problem for the near future.
1787-
if (CD->isTrivial() && CD->isDefaultConstructor()) {
1788-
const auto *cxxrd =
1789-
cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl());
1790-
// Some cases, such as member pointer members, can't be zero
1791-
// initialized. These are "zero-initialized" in the language standard
1792-
// sense, but the target ABI may require that a literal value other
1793-
// than zero be used in the initializer to make clear that a pointer
1794-
// with the value zero is not what is intended. The classic codegen
1795-
// goes through emitNullConstant for those cases but generates a
1796-
// non-zero constant. We can't quite do that here because we need an
1797-
// attribute and not a value, but something like that can be
1798-
// implemented.
1799-
if (!CGM.getTypes().isZeroInitializable(cxxrd)) {
1800-
llvm_unreachable("NYI");
1801-
}
1802-
return cir::ZeroAttr::get(CGM.convertType(D.getType()));
1803-
}
1784+
if (CD->isTrivial() && CD->isDefaultConstructor())
1785+
return CGM.emitNullConstant(D.getType());
18041786
}
18051787
}
18061788
}
@@ -1820,8 +1802,11 @@ mlir::Attribute ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
18201802

18211803
// Try to emit the initializer. Note that this can allow some things that
18221804
// are not allowed by tryEmitPrivateForMemory alone.
1823-
if (auto value = D.evaluateValue())
1805+
if (auto value = D.evaluateValue()) {
1806+
assert(!value->allowConstexprUnknown() &&
1807+
"Constexpr unknown values are not allowed in CodeGen");
18241808
return tryEmitPrivateForMemory(*value, destType);
1809+
}
18251810

18261811
return nullptr;
18271812
}
@@ -2109,14 +2094,14 @@ mlir::TypedAttr CIRGenModule::emitNullConstant(QualType T) {
21092094
llvm_unreachable("NYI");
21102095
}
21112096

2112-
if (T->getAs<clang::RecordType>())
2113-
llvm_unreachable("NYI");
2097+
if (const RecordType *rt = T->getAs<RecordType>())
2098+
return ::emitNullConstant(*this, rt->getDecl(), /*complete object*/
2099+
true);
21142100

21152101
assert(T->isMemberDataPointerType() &&
21162102
"Should only see pointers to data members here!");
21172103

2118-
llvm_unreachable("NYI");
2119-
return {};
2104+
return getCXXABI().emitNullMemberPointer(T);
21202105
}
21212106

21222107
mlir::Value CIRGenModule::emitMemberPointerConstant(const UnaryOperator *E) {

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
123123

124124
bool classifyReturnType(CIRGenFunctionInfo &FI) const override;
125125
bool isZeroInitializable(const MemberPointerType *MPT) override;
126+
mlir::TypedAttr emitNullMemberPointer(clang::QualType T) override;
126127

127128
AddedStructorArgCounts
128129
buildStructorSignature(GlobalDecl GD,
@@ -2749,6 +2750,21 @@ bool CIRGenItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
27492750
return MPT->isMemberFunctionPointer();
27502751
}
27512752

2753+
mlir::TypedAttr CIRGenItaniumCXXABI::emitNullMemberPointer(clang::QualType T) {
2754+
auto *MPT = T->getAs<MemberPointerType>();
2755+
// Itanium C++ ABI 2.3:
2756+
// A NULL pointer is represented as -1.
2757+
//
2758+
// Note that CIR uses a DataMemberAttr without member_index to get
2759+
// #cir.data_member<null>, lowering shall later transform it into -1.
2760+
if (MPT->isMemberDataPointer())
2761+
return cir::DataMemberAttr::get(
2762+
cast<cir::DataMemberType>(CGM.convertType(T)));
2763+
2764+
// Create an annon struct with two constant int of CGM.PtrDiffTy size.
2765+
llvm_unreachable("NYI");
2766+
}
2767+
27522768
/// The Itanium ABI always places an offset to the complete object
27532769
/// at entry -2 in the vtable.
27542770
void CIRGenItaniumCXXABI::emitVirtualObjectDelete(

clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,27 +1333,30 @@ void LoweringPreparePass::lowerDynamicCastOp(DynamicCastOp op) {
13331333

13341334
static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
13351335
mlir::Operation *op, mlir::Type eltTy,
1336-
mlir::Value arrayAddr,
1337-
uint64_t arrayLen) {
1336+
mlir::Value arrayAddr, uint64_t arrayLen,
1337+
bool isCtor) {
13381338
// Generate loop to call into ctor/dtor for every element.
13391339
auto loc = op->getLoc();
13401340

13411341
// TODO: instead of fixed integer size, create alias for PtrDiffTy and unify
13421342
// with CIRGen stuff.
13431343
auto ptrDiffTy =
13441344
cir::IntType::get(builder.getContext(), 64, /*signed=*/false);
1345-
auto numArrayElementsConst = builder.create<cir::ConstantOp>(
1346-
loc, ptrDiffTy, cir::IntAttr::get(ptrDiffTy, arrayLen));
1345+
uint64_t endOffset = isCtor ? arrayLen : arrayLen - 1;
1346+
mlir::Value endOffsetVal = builder.create<cir::ConstantOp>(
1347+
loc, ptrDiffTy, cir::IntAttr::get(ptrDiffTy, endOffset));
13471348

13481349
auto begin = builder.create<cir::CastOp>(
13491350
loc, eltTy, cir::CastKind::array_to_ptrdecay, arrayAddr);
1350-
mlir::Value end = builder.create<cir::PtrStrideOp>(loc, eltTy, begin,
1351-
numArrayElementsConst);
1351+
mlir::Value end =
1352+
builder.create<cir::PtrStrideOp>(loc, eltTy, begin, endOffsetVal);
1353+
mlir::Value start = isCtor ? begin : end;
1354+
mlir::Value stop = isCtor ? end : begin;
13521355

13531356
auto tmpAddr = builder.createAlloca(
13541357
loc, /*addr type*/ builder.getPointerTo(eltTy),
13551358
/*var type*/ eltTy, "__array_idx", clang::CharUnits::One());
1356-
builder.createStore(loc, begin, tmpAddr);
1359+
builder.createStore(loc, start, tmpAddr);
13571360

13581361
auto loop = builder.createDoWhile(
13591362
loc,
@@ -1362,7 +1365,7 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
13621365
auto currentElement = b.create<cir::LoadOp>(loc, eltTy, tmpAddr);
13631366
mlir::Type boolTy = cir::BoolType::get(b.getContext());
13641367
auto cmp = builder.create<cir::CmpOp>(loc, boolTy, cir::CmpOpKind::ne,
1365-
currentElement, end);
1368+
currentElement, stop);
13661369
builder.createCondition(cmp);
13671370
},
13681371
/*bodyBuilder=*/
@@ -1373,15 +1376,20 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
13731376
op->walk([&](CallOp c) { ctorCall = c; });
13741377
assert(ctorCall && "expected ctor call");
13751378

1376-
auto one = builder.create<cir::ConstantOp>(
1377-
loc, ptrDiffTy, cir::IntAttr::get(ptrDiffTy, 1));
1379+
cir::ConstantOp stride;
1380+
if (isCtor)
1381+
stride = builder.create<cir::ConstantOp>(
1382+
loc, ptrDiffTy, cir::IntAttr::get(ptrDiffTy, 1));
1383+
else
1384+
stride = builder.create<cir::ConstantOp>(
1385+
loc, ptrDiffTy, cir::IntAttr::get(ptrDiffTy, -1));
13781386

1379-
ctorCall->moveAfter(one);
1387+
ctorCall->moveBefore(stride);
13801388
ctorCall->setOperand(0, currentElement);
13811389

13821390
// Advance pointer and store them to temporary variable
1383-
auto nextElement =
1384-
builder.create<cir::PtrStrideOp>(loc, eltTy, currentElement, one);
1391+
auto nextElement = builder.create<cir::PtrStrideOp>(
1392+
loc, eltTy, currentElement, stride);
13851393
builder.createStore(loc, nextElement, tmpAddr);
13861394
builder.createYield(loc);
13871395
});
@@ -1397,7 +1405,7 @@ void LoweringPreparePass::lowerArrayDtor(ArrayDtor op) {
13971405
auto eltTy = op->getRegion(0).getArgument(0).getType();
13981406
auto arrayLen =
13991407
mlir::cast<cir::ArrayType>(op.getAddr().getType().getPointee()).getSize();
1400-
lowerArrayDtorCtorIntoLoop(builder, op, eltTy, op.getAddr(), arrayLen);
1408+
lowerArrayDtorCtorIntoLoop(builder, op, eltTy, op.getAddr(), arrayLen, false);
14011409
}
14021410

14031411
static std::string getGlobalVarNameForConstString(cir::StoreOp op,
@@ -1460,7 +1468,7 @@ void LoweringPreparePass::lowerArrayCtor(ArrayCtor op) {
14601468
auto eltTy = op->getRegion(0).getArgument(0).getType();
14611469
auto arrayLen =
14621470
mlir::cast<cir::ArrayType>(op.getAddr().getType().getPointee()).getSize();
1463-
lowerArrayDtorCtorIntoLoop(builder, op, eltTy, op.getAddr(), arrayLen);
1471+
lowerArrayDtorCtorIntoLoop(builder, op, eltTy, op.getAddr(), arrayLen, true);
14641472
}
14651473

14661474
void LoweringPreparePass::lowerStdFindOp(StdFindOp op) {

0 commit comments

Comments
 (0)