Skip to content

Commit 9af893f

Browse files
committed
[CIR] Add alignment support for global, store, and load ops
This adds alignment support for GlobalOp, LoadOp, and StoreOp. Tests which failed because cir.store now prints alignment were updated with wildcard matches, except where the alignment was relevant to the test. Tests which check for cir.store in cases that don't have explicit alignment were not updated. The alignment for loads from structures and unions is incorrect both here and in the incubator. That will be fixed in a separate patch.
1 parent e9304cb commit 9af893f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1108
-820
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,19 +184,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
184184
global.getSymName());
185185
}
186186

187-
cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
188-
bool isVolatile = false, uint64_t alignment = 0) {
189-
mlir::IntegerAttr intAttr;
190-
if (alignment)
191-
intAttr = mlir::IntegerAttr::get(
192-
mlir::IntegerType::get(ptr.getContext(), 64), alignment);
193-
194-
return create<cir::LoadOp>(loc, ptr);
195-
}
196-
197-
cir::StoreOp createStore(mlir::Location loc, mlir::Value val,
198-
mlir::Value dst) {
199-
return create<cir::StoreOp>(loc, val, dst);
187+
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
188+
mlir::IntegerAttr align = {}) {
189+
return create<cir::StoreOp>(loc, val, dst, align);
200190
}
201191

202192
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
@@ -209,7 +199,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
209199
clang::CharUnits alignment) {
210200
auto addr = createAlloca(loc, getPointerTo(type), type, {},
211201
getSizeFromCharUnits(getContext(), alignment));
212-
return createLoad(loc, addr);
202+
mlir::IntegerAttr alignAttr;
203+
uint64_t align = alignment.getQuantity();
204+
if (align)
205+
alignAttr = getI64IntegerAttr(align);
206+
207+
return create<cir::LoadOp>(loc, addr, /*isDeref=*/false, alignAttr);
213208
}
214209

215210
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,15 @@ def LoadOp : CIR_Op<"load", [
417417
}];
418418

419419
let arguments = (ins Arg<CIR_PointerType, "the address to load from",
420-
[MemRead]>:$addr, UnitAttr:$isDeref);
420+
[MemRead]>:$addr,
421+
UnitAttr:$isDeref,
422+
OptionalAttr<I64Attr>:$alignment
423+
);
421424
let results = (outs CIR_AnyType:$result);
422425

423426
let assemblyFormat = [{
424427
(`deref` $isDeref^)?
428+
(`align` `(` $alignment^ `)`)?
425429
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
426430
}];
427431

@@ -458,9 +462,11 @@ def StoreOp : CIR_Op<"store", [
458462

459463
let arguments = (ins CIR_AnyType:$value,
460464
Arg<CIR_PointerType, "the address to store the value",
461-
[MemWrite]>:$addr);
465+
[MemWrite]>:$addr,
466+
OptionalAttr<I64Attr>:$alignment);
462467

463468
let assemblyFormat = [{
469+
(`align` `(` $alignment^ `)`)?
464470
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
465471
}];
466472

@@ -1643,7 +1649,8 @@ def GlobalOp : CIR_Op<"global"> {
16431649
TypeAttr:$sym_type,
16441650
Arg<GlobalLinkageKind, "linkage type">:$linkage,
16451651
OptionalAttr<AnyAttr>:$initial_value,
1646-
UnitAttr:$dsolocal);
1652+
UnitAttr:$dsolocal,
1653+
OptionalAttr<I64Attr>:$alignment);
16471654

16481655
let assemblyFormat = [{
16491656
$linkage

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@ struct MissingFeatures {
3434
static bool opGlobalDSOLocal() { return false; }
3535
static bool opGlobalThreadLocal() { return false; }
3636
static bool opGlobalConstant() { return false; }
37-
static bool opGlobalAlignment() { return false; }
3837
static bool opGlobalWeakRef() { return false; }
3938
static bool opGlobalLinkage() { return false; }
40-
static bool opGlobalSetVisitibility() { return false; }
4139
static bool opGlobalUnnamedAddr() { return false; }
40+
static bool opGlobalSection() { return false; }
41+
static bool opGlobalVisibility() { return false; }
42+
static bool opGlobalDLLImportExport() { return false; }
43+
static bool opGlobalPartition() { return false; }
44+
static bool opGlobalCIRGlobalValueInterface() { return false; }
4245

4346
static bool supportIFuncAttr() { return false; }
4447
static bool supportVisibility() { return false; }
@@ -51,7 +54,6 @@ struct MissingFeatures {
5154
static bool opLoadStoreTbaa() { return false; }
5255
static bool opLoadStoreMemOrder() { return false; }
5356
static bool opLoadStoreVolatile() { return false; }
54-
static bool opLoadStoreAlignment() { return false; }
5557
static bool opLoadStoreAtomic() { return false; }
5658
static bool opLoadStoreObjC() { return false; }
5759

clang/lib/CIR/CodeGen/CIRGenBuilder.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
1010
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
1111

12+
#include "Address.h"
1213
#include "CIRGenTypeCache.h"
1314
#include "clang/CIR/MissingFeatures.h"
1415

@@ -279,6 +280,26 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
279280
return create<cir::BinOp>(loc, cir::BinOpKind::Div, lhs, rhs);
280281
}
281282

283+
cir::LoadOp createLoad(mlir::Location loc, Address addr,
284+
bool isVolatile = false) {
285+
mlir::IntegerAttr align;
286+
uint64_t alignment = addr.getAlignment().getQuantity();
287+
if (alignment)
288+
align = getI64IntegerAttr(alignment);
289+
return create<cir::LoadOp>(loc, addr.getPointer(), /*isDeref=*/false, align);
290+
}
291+
292+
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst,
293+
::mlir::IntegerAttr align = {}) {
294+
if (!align) {
295+
uint64_t alignment = dst.getAlignment().getQuantity();
296+
if (alignment)
297+
align = mlir::IntegerAttr::get(mlir::IntegerType::get(getContext(), 64),
298+
alignment);
299+
}
300+
return CIRBaseBuilderTy::createStore(loc, val, dst.getPointer(), align);
301+
}
302+
282303
/// Create a cir.ptr_stride operation to get access to an array element.
283304
/// \p idx is the index of the element to access, \p shouldDecay is true if
284305
/// the result should decay to a pointer to the element type.

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,10 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst,
209209
// Read/modify/write the vector, inserting the new element
210210
const mlir::Location loc = dst.getVectorPointer().getLoc();
211211
const mlir::Value vector =
212-
builder.createLoad(loc, dst.getVectorAddress().getPointer());
212+
builder.createLoad(loc, dst.getVectorAddress());
213213
const mlir::Value newVector = builder.create<cir::VecInsertOp>(
214214
loc, vector, src.getScalarVal(), dst.getVectorIdx());
215-
builder.createStore(loc, newVector, dst.getVectorAddress().getPointer());
215+
builder.createStore(loc, newVector, dst.getVectorAddress());
216216
return;
217217
}
218218

@@ -301,7 +301,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
301301
}
302302

303303
assert(currSrcLoc && "must pass in source location");
304-
builder.createStore(*currSrcLoc, value, addr.getPointer() /*, isVolatile*/);
304+
builder.createStore(*currSrcLoc, value, addr /*, isVolatile*/);
305305

306306
if (isNontemporal) {
307307
cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
@@ -409,12 +409,10 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
409409
Address addr = lvalue.getAddress();
410410
mlir::Type eltTy = addr.getElementType();
411411

412-
mlir::Value ptr = addr.getPointer();
413412
if (mlir::isa<cir::VoidType>(eltTy))
414413
cgm.errorNYI(loc, "emitLoadOfScalar: void type");
415414

416-
mlir::Value loadOp = builder.CIRBaseBuilderTy::createLoad(
417-
getLoc(loc), ptr, false /*isVolatile*/);
415+
mlir::Value loadOp = builder.createLoad(getLoc(loc), addr);
418416

419417
return loadOp;
420418
}
@@ -431,7 +429,7 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
431429

432430
if (lv.isVectorElt()) {
433431
const mlir::Value load =
434-
builder.createLoad(getLoc(loc), lv.getVectorAddress().getPointer());
432+
builder.createLoad(getLoc(loc), lv.getVectorAddress());
435433
return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load,
436434
lv.getVectorIdx()));
437435
}
@@ -745,11 +743,12 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
745743

746744
LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e) {
747745
cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e);
748-
assert(!cir::MissingFeatures::opGlobalAlignment());
746+
assert(globalOp.getAlignment() && "expected alignment for string literal");
747+
unsigned align = *(globalOp.getAlignment());
749748
mlir::Value addr =
750749
builder.createGetGlobal(getLoc(e->getSourceRange()), globalOp);
751750
return makeAddrLValue(
752-
Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(1)),
751+
Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(align)),
753752
e->getType(), AlignmentSource::Decl);
754753
}
755754

clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,
163163
// TODO(CIR): Replace this part later with cir::DoWhileOp
164164
for (unsigned i = numInitElements; i != numArrayElements; ++i) {
165165
cir::LoadOp currentElement =
166-
builder.createLoad(loc, tmpAddr.getPointer());
166+
builder.createLoad(loc, tmpAddr);
167167

168168
// Emit the actual filler expression.
169169
const LValue elementLV = cgf.makeAddrLValue(

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
607607
// respective address.
608608
// Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);
609609
const mlir::Value zeroValue = builder.getNullValue(convertType(ty), loc);
610-
builder.createStore(loc, zeroValue, destPtr.getPointer());
610+
builder.createStore(loc, zeroValue, destPtr);
611611
}
612612

613613
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,39 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
366366
CIRGenModule::createGlobalOp(*this, loc, mangledName, ty,
367367
/*insertPoint=*/entry.getOperation());
368368

369+
// Handle things which are present even on external declarations.
370+
if (d) {
371+
if (langOpts.OpenMP && !langOpts.OpenMPSimd)
372+
errorNYI(d->getSourceRange(), "OpenMP target global variable");
373+
374+
gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
375+
assert(!cir::MissingFeatures::opGlobalConstant());
376+
assert(!cir::MissingFeatures::opGlobalLinkage());
377+
378+
if (d->getTLSKind())
379+
errorNYI(d->getSourceRange(), "thread local global variable");
380+
381+
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
382+
assert(!cir::MissingFeatures::opGlobalPartition());
383+
assert(!cir::MissingFeatures::setDSOLocal());
384+
385+
// If required by the ABI, treat declarations of static data members with
386+
// inline initializers as definitions.
387+
if (astContext.isMSStaticDataMemberInlineDefinition(d))
388+
errorNYI(d->getSourceRange(), "MS static data member inline definition");
389+
390+
assert(!cir::MissingFeatures::opGlobalSection());
391+
assert(!cir::MissingFeatures::opGlobalVisibility());
392+
393+
// Handle XCore specific ABI requirements.
394+
if (getTriple().getArch() == llvm::Triple::xcore)
395+
errorNYI(d->getSourceRange(), "XCore specific ABI requirements");
396+
397+
// We need to check for external const declarations with initializers here,
398+
// but the 'isPublic()' part of the check uses the CIRGlobalValueInterface.
399+
assert(!cir::MissingFeatures::opGlobalCIRGlobalValueInterface());
400+
}
401+
369402
return gv;
370403
}
371404

@@ -775,7 +808,8 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
775808

776809
static cir::GlobalOp generateStringLiteral(mlir::Location loc,
777810
mlir::TypedAttr c, CIRGenModule &cgm,
778-
StringRef globalName) {
811+
StringRef globalName,
812+
CharUnits alignment) {
779813
assert(!cir::MissingFeatures::addressSpace());
780814

781815
// Create a global variable for this string
@@ -784,7 +818,7 @@ static cir::GlobalOp generateStringLiteral(mlir::Location loc,
784818
CIRGenModule::createGlobalOp(cgm, loc, globalName, c.getType());
785819

786820
// Set up extra information and add to the module
787-
assert(!cir::MissingFeatures::opGlobalAlignment());
821+
gv.setAlignmentAttr(cgm.getSize(alignment));
788822
assert(!cir::MissingFeatures::opGlobalLinkage());
789823
assert(!cir::MissingFeatures::opGlobalThreadLocal());
790824
assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
@@ -821,6 +855,9 @@ std::string CIRGenModule::getUniqueGlobalName(const std::string &baseName) {
821855
/// Return a pointer to a constant array for the given string literal.
822856
cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
823857
StringRef name) {
858+
CharUnits alignment =
859+
astContext.getAlignOfGlobalVarInChars(s->getType(), /*VD=*/nullptr);
860+
824861
mlir::Attribute c = getConstantArrayFromStringLiteral(s);
825862

826863
if (getLangOpts().WritableStrings) {
@@ -842,8 +879,8 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
842879
std::string uniqueName = getUniqueGlobalName(name.str());
843880
mlir::Location loc = getLoc(s->getSourceRange());
844881
auto typedC = llvm::cast<mlir::TypedAttr>(c);
845-
assert(!cir::MissingFeatures::opGlobalAlignment());
846-
cir::GlobalOp gv = generateStringLiteral(loc, typedC, *this, uniqueName);
882+
cir::GlobalOp gv =
883+
generateStringLiteral(loc, typedC, *this, uniqueName, alignment);
847884
assert(!cir::MissingFeatures::opGlobalDSOLocal());
848885

849886
assert(!cir::MissingFeatures::sanitizers());
@@ -918,7 +955,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
918955
void CIRGenModule::setInitializer(cir::GlobalOp &op, mlir::Attribute value) {
919956
// Recompute visibility when updating initializer.
920957
op.setInitialValueAttr(value);
921-
assert(!cir::MissingFeatures::opGlobalSetVisitibility());
958+
assert(!cir::MissingFeatures::opGlobalVisibility());
922959
}
923960

924961
cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) {
391391
// If this function returns a reference, take the address of the
392392
// expression rather than the value.
393393
RValue result = emitReferenceBindingToExpr(rv);
394-
builder.createStore(loc, result.getScalarVal(), *fnRetAlloca);
394+
builder.CIRBaseBuilderTy::createStore(loc, result.getScalarVal(),
395+
*fnRetAlloca);
395396
} else {
396397
mlir::Value value = nullptr;
397398
switch (CIRGenFunction::getEvaluationKind(rv->getType())) {

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
353353
offset += dataLayout.getTypeSize(ty);
354354
}
355355

356+
// Account for padding, if necessary, for the alignment of the field whose
357+
// offset we are calculating.
358+
const llvm::Align tyAlign = llvm::Align(
359+
getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
360+
offset = llvm::alignTo(offset, tyAlign);
361+
356362
return offset;
357363
}
358364

0 commit comments

Comments
 (0)