// Private variable with an initial value.
memref.global "private" @x : memref<2xf32> = dense<0.0,2.0>
+ // Private variable with an initial value and an alignment (power of 2).
+ memref.global "private" @x : memref<2xf32> = dense<0.0,2.0> {alignment = 64}
+
// Declaration of an external variable.
memref.global "private" @y : memref<4xi32>
OptionalAttr<StrAttr>:$sym_visibility,
MemRefTypeAttr:$type,
OptionalAttr<AnyAttr>:$initial_value,
- UnitAttr:$constant
+ UnitAttr:$constant,
+ OptionalAttr<I64Attr>:$alignment
);
let assemblyFormat = [{
initialValue = elementsAttr.getValue({});
}
+ uint64_t alignment = global.alignment().getValueOr(0);
+
auto newGlobal = rewriter.replaceOpWithNewOp<LLVM::GlobalOp>(
global, arrayTy, global.constant(), linkage, global.sym_name(),
- initialValue, /*alignment=*/0, type.getMemorySpaceAsInt());
+ initialValue, alignment, type.getMemorySpaceAsInt());
if (!global.isExternal() && global.isUninitialized()) {
Block *blk = new Block();
newGlobal.getInitializerRegion().push_back(blk);
}
}
+ if (Optional<uint64_t> alignAttr = op.alignment()) {
+ uint64_t alignment = alignAttr.getValue();
+
+ if (!llvm::isPowerOf2_64(alignment))
+ return op->emitError() << "alignment attribute value " << alignment
+ << " is not a power of 2";
+ }
+
// TODO: verify visibility for declarations.
return success();
}
/*sym_visibility=*/globalBuilder.getStringAttr("private"),
/*type=*/typeConverter.convertType(type).cast<MemRefType>(),
/*initial_value=*/constantOp.getValue().cast<ElementsAttr>(),
- /*constant=*/true);
+ /*constant=*/true,
+ /*alignment=*/IntegerAttr());
symbolTable.insert(global);
// The symbol table inserts at the end of the module, but globals are a bit
// nicer if they are at the beginning.
return
}
+// Test scalar memref with an alignment.
+// CHECK: llvm.mlir.global private @gv4(1.000000e+00 : f32) {alignment = 64 : i64} : f32
+memref.global "private" @gv4 : memref<f32> = dense<1.0> {alignment = 64}
+
// -----
func @collapse_shape_static(%arg0: memref<1x3x4x1x5xf32>) -> memref<3x4x5xf32> {
// -----
+// expected-error @+1 {{alignment attribute value 63 is not a power of 2}}
+memref.global "private" @gv : memref<4xf32> = dense<1.0> { alignment = 63 }
+
+// -----
+
func @copy_different_shape(%arg0: memref<2xf32>, %arg1: memref<3xf32>) {
// expected-error @+1 {{op requires the same shape for all operands}}
memref.copy %arg0, %arg1 : memref<2xf32> to memref<3xf32>