[clang] [CIR] Add alignment support for global, store, and load ops (PR #141163)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 22 16:49:45 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Andy Kaylor (andykaylor)
<details>
<summary>Changes</summary>
This adds alignment support for GlobalOp, LoadOp, and StoreOp.
Tests which failed because cir.store/cir.load now print alignment were updated with wildcard matches, except where the alignment was relevant to the test. Tests which check for cir.store/cir.load in cases that don't have explicit alignment were not updated.
New tests for alignment are alignment.c, align-load.c, and align-store.c.
---
Patch is 289.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/141163.diff
53 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+9-14)
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+10-3)
- (modified) clang/include/clang/CIR/MissingFeatures.h (+5-3)
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+21)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+8-9)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp (+1-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+1-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+42-5)
- (modified) clang/lib/CIR/CodeGen/CIRGenStmt.cpp (+2-1)
- (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (+6)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+8-8)
- (added) clang/test/CIR/CodeGen/align-load.c (+96)
- (added) clang/test/CIR/CodeGen/align-store.c (+94)
- (added) clang/test/CIR/CodeGen/alignment.c (+26)
- (modified) clang/test/CIR/CodeGen/array.cpp (+46-46)
- (modified) clang/test/CIR/CodeGen/basic.c (+24-24)
- (modified) clang/test/CIR/CodeGen/basic.cpp (+37-37)
- (modified) clang/test/CIR/CodeGen/binassign.c (+4-4)
- (modified) clang/test/CIR/CodeGen/binop.cpp (+40-40)
- (modified) clang/test/CIR/CodeGen/call.cpp (+1-1)
- (modified) clang/test/CIR/CodeGen/cast.cpp (+4-4)
- (modified) clang/test/CIR/CodeGen/cmp.cpp (+50-50)
- (modified) clang/test/CIR/CodeGen/comma.c (+5-5)
- (modified) clang/test/CIR/CodeGen/compound_assign.cpp (+10-10)
- (modified) clang/test/CIR/CodeGen/forrange.cpp (+24-24)
- (modified) clang/test/CIR/CodeGen/if.cpp (+21-21)
- (modified) clang/test/CIR/CodeGen/local-vars.cpp (+14-13)
- (modified) clang/test/CIR/CodeGen/loop.cpp (+33-33)
- (modified) clang/test/CIR/CodeGen/namespace.cpp (+3-3)
- (modified) clang/test/CIR/CodeGen/nullptr-init.cpp (+3-3)
- (modified) clang/test/CIR/CodeGen/pointers.cpp (+6-6)
- (modified) clang/test/CIR/CodeGen/struct.c (+17-17)
- (modified) clang/test/CIR/CodeGen/struct.cpp (+2-2)
- (modified) clang/test/CIR/CodeGen/switch.cpp (+7-7)
- (modified) clang/test/CIR/CodeGen/switch_flat_op.cpp (+10-10)
- (modified) clang/test/CIR/CodeGen/unary.cpp (+51-51)
- (modified) clang/test/CIR/CodeGen/union.c (+24-24)
- (modified) clang/test/CIR/CodeGen/union.cpp (+4-4)
- (modified) clang/test/CIR/CodeGen/vector-ext.cpp (+70-70)
- (modified) clang/test/CIR/CodeGen/vector.cpp (+70-70)
- (modified) clang/test/CIR/CodeGenOpenACC/combined.cpp (+51-51)
- (modified) clang/test/CIR/CodeGenOpenACC/data.c (+13-13)
- (modified) clang/test/CIR/CodeGenOpenACC/init.c (+4-4)
- (modified) clang/test/CIR/CodeGenOpenACC/kernels.c (+27-27)
- (modified) clang/test/CIR/CodeGenOpenACC/loop.cpp (+22-22)
- (modified) clang/test/CIR/CodeGenOpenACC/parallel.c (+29-29)
- (modified) clang/test/CIR/CodeGenOpenACC/serial.c (+16-16)
- (modified) clang/test/CIR/CodeGenOpenACC/set.c (+5-5)
- (modified) clang/test/CIR/CodeGenOpenACC/shutdown.c (+4-4)
- (modified) clang/test/CIR/CodeGenOpenACC/wait.c (+5-5)
- (modified) clang/test/CIR/Lowering/array.cpp (+3-2)
- (modified) clang/test/CIR/Lowering/local-vars.cpp (+4-3)
- (modified) clang/test/CIR/Lowering/unary-expr-or-type-trait.cpp (+16-15)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 738f33bf36c9e..9de3a66755778 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -184,19 +184,9 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
global.getSymName());
}
- cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
- bool isVolatile = false, uint64_t alignment = 0) {
- mlir::IntegerAttr intAttr;
- if (alignment)
- intAttr = mlir::IntegerAttr::get(
- mlir::IntegerType::get(ptr.getContext(), 64), alignment);
-
- return create<cir::LoadOp>(loc, ptr);
- }
-
- cir::StoreOp createStore(mlir::Location loc, mlir::Value val,
- mlir::Value dst) {
- return create<cir::StoreOp>(loc, val, dst);
+ cir::StoreOp createStore(mlir::Location loc, mlir::Value val, mlir::Value dst,
+ mlir::IntegerAttr align = {}) {
+ return create<cir::StoreOp>(loc, val, dst, align);
}
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
@@ -209,7 +199,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
clang::CharUnits alignment) {
auto addr = createAlloca(loc, getPointerTo(type), type, {},
getSizeFromCharUnits(getContext(), alignment));
- return createLoad(loc, addr);
+ mlir::IntegerAttr alignAttr;
+ uint64_t align = alignment.getQuantity();
+ if (align)
+ alignAttr = getI64IntegerAttr(align);
+
+ return create<cir::LoadOp>(loc, addr, /*isDeref=*/false, alignAttr);
}
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 8267df92e3187..eaa4c9702137c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -417,11 +417,15 @@ def LoadOp : CIR_Op<"load", [
}];
let arguments = (ins Arg<CIR_PointerType, "the address to load from",
- [MemRead]>:$addr, UnitAttr:$isDeref);
+ [MemRead]>:$addr,
+ UnitAttr:$isDeref,
+ OptionalAttr<I64Attr>:$alignment
+ );
let results = (outs CIR_AnyType:$result);
let assemblyFormat = [{
(`deref` $isDeref^)?
+ (`align` `(` $alignment^ `)`)?
$addr `:` qualified(type($addr)) `,` type($result) attr-dict
}];
@@ -458,9 +462,11 @@ def StoreOp : CIR_Op<"store", [
let arguments = (ins CIR_AnyType:$value,
Arg<CIR_PointerType, "the address to store the value",
- [MemWrite]>:$addr);
+ [MemWrite]>:$addr,
+ OptionalAttr<I64Attr>:$alignment);
let assemblyFormat = [{
+ (`align` `(` $alignment^ `)`)?
$value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr))
}];
@@ -1643,7 +1649,8 @@ def GlobalOp : CIR_Op<"global"> {
TypeAttr:$sym_type,
Arg<GlobalLinkageKind, "linkage type">:$linkage,
OptionalAttr<AnyAttr>:$initial_value,
- UnitAttr:$dsolocal);
+ UnitAttr:$dsolocal,
+ OptionalAttr<I64Attr>:$alignment);
let assemblyFormat = [{
$linkage
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index d4952da326ac0..fb205e9cd85d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -34,11 +34,14 @@ struct MissingFeatures {
static bool opGlobalDSOLocal() { return false; }
static bool opGlobalThreadLocal() { return false; }
static bool opGlobalConstant() { return false; }
- static bool opGlobalAlignment() { return false; }
static bool opGlobalWeakRef() { return false; }
static bool opGlobalLinkage() { return false; }
- static bool opGlobalSetVisitibility() { return false; }
static bool opGlobalUnnamedAddr() { return false; }
+ static bool opGlobalSection() { return false; }
+ static bool opGlobalVisibility() { return false; }
+ static bool opGlobalDLLImportExport() { return false; }
+ static bool opGlobalPartition() { return false; }
+ static bool opGlobalCIRGlobalValueInterface() { return false; }
static bool supportIFuncAttr() { return false; }
static bool supportVisibility() { return false; }
@@ -51,7 +54,6 @@ struct MissingFeatures {
static bool opLoadStoreTbaa() { return false; }
static bool opLoadStoreMemOrder() { return false; }
static bool opLoadStoreVolatile() { return false; }
- static bool opLoadStoreAlignment() { return false; }
static bool opLoadStoreAtomic() { return false; }
static bool opLoadStoreObjC() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index 9c0968f144eef..5e56aa9e740e6 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H
+#include "Address.h"
#include "CIRGenTypeCache.h"
#include "clang/CIR/MissingFeatures.h"
@@ -279,6 +280,26 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return create<cir::BinOp>(loc, cir::BinOpKind::Div, lhs, rhs);
}
+ cir::LoadOp createLoad(mlir::Location loc, Address addr,
+ bool isVolatile = false) {
+ mlir::IntegerAttr align;
+ uint64_t alignment = addr.getAlignment().getQuantity();
+ if (alignment)
+ align = getI64IntegerAttr(alignment);
+ return create<cir::LoadOp>(loc, addr.getPointer(), /*isDeref=*/false, align);
+ }
+
+ cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst,
+ ::mlir::IntegerAttr align = {}) {
+ if (!align) {
+ uint64_t alignment = dst.getAlignment().getQuantity();
+ if (alignment)
+ align = mlir::IntegerAttr::get(mlir::IntegerType::get(getContext(), 64),
+ alignment);
+ }
+ return CIRBaseBuilderTy::createStore(loc, val, dst.getPointer(), align);
+ }
+
/// Create a cir.ptr_stride operation to get access to an array element.
/// \p idx is the index of the element to access, \p shouldDecay is true if
/// the result should decay to a pointer to the element type.
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index a8fecafe4a1f3..5424c6a8d6f3c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -209,10 +209,10 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst,
// Read/modify/write the vector, inserting the new element
const mlir::Location loc = dst.getVectorPointer().getLoc();
const mlir::Value vector =
- builder.createLoad(loc, dst.getVectorAddress().getPointer());
+ builder.createLoad(loc, dst.getVectorAddress());
const mlir::Value newVector = builder.create<cir::VecInsertOp>(
loc, vector, src.getScalarVal(), dst.getVectorIdx());
- builder.createStore(loc, newVector, dst.getVectorAddress().getPointer());
+ builder.createStore(loc, newVector, dst.getVectorAddress());
return;
}
@@ -301,7 +301,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr,
}
assert(currSrcLoc && "must pass in source location");
- builder.createStore(*currSrcLoc, value, addr.getPointer() /*, isVolatile*/);
+ builder.createStore(*currSrcLoc, value, addr /*, isVolatile*/);
if (isNontemporal) {
cgm.errorNYI(addr.getPointer().getLoc(), "emitStoreOfScalar nontemporal");
@@ -409,12 +409,10 @@ mlir::Value CIRGenFunction::emitLoadOfScalar(LValue lvalue,
Address addr = lvalue.getAddress();
mlir::Type eltTy = addr.getElementType();
- mlir::Value ptr = addr.getPointer();
if (mlir::isa<cir::VoidType>(eltTy))
cgm.errorNYI(loc, "emitLoadOfScalar: void type");
- mlir::Value loadOp = builder.CIRBaseBuilderTy::createLoad(
- getLoc(loc), ptr, false /*isVolatile*/);
+ mlir::Value loadOp = builder.createLoad(getLoc(loc), addr);
return loadOp;
}
@@ -431,7 +429,7 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
if (lv.isVectorElt()) {
const mlir::Value load =
- builder.createLoad(getLoc(loc), lv.getVectorAddress().getPointer());
+ builder.createLoad(getLoc(loc), lv.getVectorAddress());
return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load,
lv.getVectorIdx()));
}
@@ -745,11 +743,12 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e) {
cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e);
- assert(!cir::MissingFeatures::opGlobalAlignment());
+ assert(globalOp.getAlignment() && "expected alignment for string literal");
+ unsigned align = *(globalOp.getAlignment());
mlir::Value addr =
builder.createGetGlobal(getLoc(e->getSourceRange()), globalOp);
return makeAddrLValue(
- Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(1)),
+ Address(addr, globalOp.getSymType(), CharUnits::fromQuantity(align)),
e->getType(), AlignmentSource::Decl);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index e006a77c6e7d6..ea354845f449c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -163,7 +163,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy,
// TODO(CIR): Replace this part later with cir::DoWhileOp
for (unsigned i = numInitElements; i != numArrayElements; ++i) {
cir::LoadOp currentElement =
- builder.createLoad(loc, tmpAddr.getPointer());
+ builder.createLoad(loc, tmpAddr);
// Emit the actual filler expression.
const LValue elementLV = cgf.makeAddrLValue(
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index ce88e656a38e8..4335214d77b7d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -607,7 +607,7 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
// respective address.
// Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);
const mlir::Value zeroValue = builder.getNullValue(convertType(ty), loc);
- builder.createStore(loc, zeroValue, destPtr.getPointer());
+ builder.createStore(loc, zeroValue, destPtr);
}
} // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index fba8c07b6860d..60a3048f548e8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -366,6 +366,39 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
CIRGenModule::createGlobalOp(*this, loc, mangledName, ty,
/*insertPoint=*/entry.getOperation());
+ // Handle things which are present even on external declarations.
+ if (d) {
+ if (langOpts.OpenMP && !langOpts.OpenMPSimd)
+ errorNYI(d->getSourceRange(), "OpenMP target global variable");
+
+ gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
+ assert(!cir::MissingFeatures::opGlobalConstant());
+ assert(!cir::MissingFeatures::opGlobalLinkage());
+
+ if (d->getTLSKind())
+ errorNYI(d->getSourceRange(), "thread local global variable");
+
+ assert(!cir::MissingFeatures::opGlobalDLLImportExport());
+ assert(!cir::MissingFeatures::opGlobalPartition());
+ assert(!cir::MissingFeatures::setDSOLocal());
+
+ // If required by the ABI, treat declarations of static data members with
+ // inline initializers as definitions.
+ if (astContext.isMSStaticDataMemberInlineDefinition(d))
+ errorNYI(d->getSourceRange(), "MS static data member inline definition");
+
+ assert(!cir::MissingFeatures::opGlobalSection());
+ assert(!cir::MissingFeatures::opGlobalVisibility());
+
+ // Handle XCore specific ABI requirements.
+ if (getTriple().getArch() == llvm::Triple::xcore)
+ errorNYI(d->getSourceRange(), "XCore specific ABI requirements");
+
+ // We need to check for external const declarations with initializers here,
+ // but the 'isPublic()' part of the check uses the CIRGlobalValueInterface.
+ assert(!cir::MissingFeatures::opGlobalCIRGlobalValueInterface());
+ }
+
return gv;
}
@@ -775,7 +808,8 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant) {
static cir::GlobalOp generateStringLiteral(mlir::Location loc,
mlir::TypedAttr c, CIRGenModule &cgm,
- StringRef globalName) {
+ StringRef globalName,
+ CharUnits alignment) {
assert(!cir::MissingFeatures::addressSpace());
// Create a global variable for this string
@@ -784,7 +818,7 @@ static cir::GlobalOp generateStringLiteral(mlir::Location loc,
CIRGenModule::createGlobalOp(cgm, loc, globalName, c.getType());
// Set up extra information and add to the module
- assert(!cir::MissingFeatures::opGlobalAlignment());
+ gv.setAlignmentAttr(cgm.getSize(alignment));
assert(!cir::MissingFeatures::opGlobalLinkage());
assert(!cir::MissingFeatures::opGlobalThreadLocal());
assert(!cir::MissingFeatures::opGlobalUnnamedAddr());
@@ -821,6 +855,9 @@ std::string CIRGenModule::getUniqueGlobalName(const std::string &baseName) {
/// Return a pointer to a constant array for the given string literal.
cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
StringRef name) {
+ CharUnits alignment =
+ astContext.getAlignOfGlobalVarInChars(s->getType(), /*VD=*/nullptr);
+
mlir::Attribute c = getConstantArrayFromStringLiteral(s);
if (getLangOpts().WritableStrings) {
@@ -842,8 +879,8 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
std::string uniqueName = getUniqueGlobalName(name.str());
mlir::Location loc = getLoc(s->getSourceRange());
auto typedC = llvm::cast<mlir::TypedAttr>(c);
- assert(!cir::MissingFeatures::opGlobalAlignment());
- cir::GlobalOp gv = generateStringLiteral(loc, typedC, *this, uniqueName);
+ cir::GlobalOp gv =
+ generateStringLiteral(loc, typedC, *this, uniqueName, alignment);
assert(!cir::MissingFeatures::opGlobalDSOLocal());
assert(!cir::MissingFeatures::sanitizers());
@@ -918,7 +955,7 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
void CIRGenModule::setInitializer(cir::GlobalOp &op, mlir::Attribute value) {
// Recompute visibility when updating initializer.
op.setInitialValueAttr(value);
- assert(!cir::MissingFeatures::opGlobalSetVisitibility());
+ assert(!cir::MissingFeatures::opGlobalVisibility());
}
cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index 763d2b087cc85..019a44636ce3c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -391,7 +391,8 @@ mlir::LogicalResult CIRGenFunction::emitReturnStmt(const ReturnStmt &s) {
// If this function returns a reference, take the address of the
// expression rather than the value.
RValue result = emitReferenceBindingToExpr(rv);
- builder.createStore(loc, result.getScalarVal(), *fnRetAlloca);
+ builder.CIRBaseBuilderTy::createStore(loc, result.getScalarVal(),
+ *fnRetAlloca);
} else {
mlir::Value value = nullptr;
switch (CIRGenFunction::getEvaluationKind(rv->getType())) {
diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index 479d249516699..b402177a5ec18 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -353,6 +353,12 @@ uint64_t RecordType::getElementOffset(const ::mlir::DataLayout &dataLayout,
offset += dataLayout.getTypeSize(ty);
}
+ // Account for padding, if necessary, for the alignment of the field whose
+ // offset we are calculating.
+ const llvm::Align tyAlign = llvm::Align(
+ getPacked() ? 1 : dataLayout.getTypeABIAlignment(members[idx]));
+ offset = llvm::alignTo(offset, tyAlign);
+
return offset;
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 3d86f3d4deffb..fbc1ec735a216 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -728,8 +728,9 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite(
const mlir::Type llvmTy = convertTypeForMemory(
*getTypeConverter(), dataLayout, op.getResult().getType());
assert(!cir::MissingFeatures::opLoadStoreMemOrder());
- assert(!cir::MissingFeatures::opLoadStoreAlignment());
- unsigned alignment = (unsigned)dataLayout.getTypeABIAlignment(llvmTy);
+ std::optional<size_t> opAlign = op.getAlignment();
+ unsigned alignment =
+ (unsigned)opAlign.value_or(dataLayout.getTypeABIAlignment(llvmTy));
assert(!cir::MissingFeatures::lowerModeOptLevel());
@@ -753,10 +754,11 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite(
cir::StoreOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
assert(!cir::MissingFeatures::opLoadStoreMemOrder());
- assert(!cir::MissingFeatures::opLoadStoreAlignment());
const mlir::Type llvmTy =
getTypeConverter()->convertType(op.getValue().getType());
- unsigned alignment = (unsigned)dataLayout.getTypeABIAlignment(llvmTy);
+ std::optional<size_t> opAlign = op.getAlignment();
+ unsigned alignment =
+ (unsigned)opAlign.value_or(dataLayout.getTypeABIAlignment(llvmTy));
assert(!cir::MissingFeatures::lowerModeOptLevel());
@@ -968,8 +970,7 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
const bool isDsoLocal = true;
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
- assert(!cir::MissingFeatures::opGlobalAlignment());
- const uint64_t alignment = 0;
+ const uint64_t alignment = op.getAlignment().value_or(0);
const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
const StringRef symbol = op.getSymName();
@@ -1024,8 +1025,7 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
const bool isDsoLocal = true;
assert(!cir::MissingFeatures::opGlobalThreadLocal());
const bool isThreadLocal = false;
- assert(!cir::MissingFeatures::opGlobalAlignment());
- const uint64_t alignment = 0;
+ const uint64_t alignment = op.getAlignment().value_or(0);
const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
const StringRef symbol = op.getSymName();
SmallVector<mlir::NamedAttribute> attributes;
diff --git a/clang/test/CIR/CodeGen/align-load.c b/clang/test/CIR/CodeGen/align-load.c
new file mode 100644
index 0000000000000..06553a307f93a
--- /dev/null
+++ b/clang/test/CIR/CodeGen/align-load.c
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -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 -Wno-unused-value -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 -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+struct S {
+ char b;
+ short s;
+ int i;
+ float f;
+ double d;
+};
+
+void accessStruct(struct S u) {
+ u.b;
+ u.s;
+ u.i;
+ u.f;
+ u.d;
+}
+
+// CIR: cir.fun...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/141163
More information about the cfe-commits
mailing list