Skip to content

Commit b3b8773

Browse files
committed
[OpenMP][MLIR] Lowering aligned clause to LLVM IR
1 parent ced15cd commit b3b8773

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,6 +1872,24 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
18721872

18731873
llvm::MapVector<llvm::Value *, llvm::Value *> alignedVars;
18741874
llvm::omp::OrderKind order = convertOrderKind(simdOp.getOrder());
1875+
llvm::BasicBlock *sourceBlock = builder.GetInsertBlock();
1876+
std::optional<ArrayAttr> alignmentValues = simdOp.getAlignments();
1877+
mlir::OperandRange operands = simdOp.getAlignedVars();
1878+
for (size_t i = 0; i < operands.size(); ++i) {
1879+
llvm::Value *alignment = nullptr;
1880+
llvm::Value *llvmVal = moduleTranslation.lookupValue(operands[i]);
1881+
llvm::Type *ty = llvmVal->getType();
1882+
if (auto intAttr = llvm::dyn_cast<IntegerAttr>((*alignmentValues)[i])) {
1883+
alignment = builder.getInt64(intAttr.getInt());
1884+
assert(ty->isPointerTy() && "Invalid type for aligned variable");
1885+
assert(alignment && "Invalid alignment value");
1886+
auto curInsert = builder.saveIP();
1887+
builder.SetInsertPoint(sourceBlock->getTerminator());
1888+
llvmVal = builder.CreateLoad(ty, llvmVal);
1889+
builder.restoreIP(curInsert);
1890+
alignedVars[llvmVal] = alignment;
1891+
}
1892+
}
18751893
ompBuilder->applySimd(loopInfo, alignedVars,
18761894
simdOp.getIfExpr()
18771895
? moduleTranslation.lookupValue(simdOp.getIfExpr())
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s
2+
3+
//CHECK-LABEL: define void @_QPsimd_aligned_pointer() {
4+
//CHECK: %[[A_PTR:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8 }, i64 1, align 8
5+
//CHECK: %[[A_VAL:.*]] = load ptr, ptr %[[A_PTR]], align 8
6+
//CHECK: omp_loop.preheader: ; preds = %0
7+
//CHECK: call void @llvm.assume(i1 true) [ "align"(ptr %[[A_VAL]], i64 256) ]
8+
llvm.func @_QPsimd_aligned_pointer() {
9+
%1 = llvm.mlir.constant(1 : i64) : i64
10+
%2 = llvm.alloca %1 x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {bindc_name = "x"} : (i64) -> !llvm.ptr
11+
%3 = llvm.alloca %1 x i32 {bindc_name = "i", pinned} : (i64) -> !llvm.ptr
12+
%4 = llvm.mlir.constant(1 : i32) : i32
13+
%5 = llvm.mlir.constant(10 : i32) : i32
14+
%6 = llvm.mlir.constant(1 : i32) : i32
15+
omp.simd aligned(%2 : !llvm.ptr -> 256 : i64) {
16+
omp.loop_nest (%arg0) : i32 = (%4) to (%5) inclusive step (%6) {
17+
llvm.store %arg0, %3 : i32, !llvm.ptr
18+
omp.yield
19+
}
20+
}
21+
llvm.return
22+
}
23+
24+
//CHECK-LABEL: define void @_QPsimd_aligned_cptr() {
25+
//CHECK: %[[A_CPTR:.*]] = alloca %_QM__fortran_builtinsT__builtin_c_ptr, i64 1, align 8
26+
//CHECK: %[[A_VAL:.*]] = load ptr, ptr %[[A_CPTR]], align 8
27+
//CHECK: omp_loop.preheader: ; preds = %0
28+
//CHECK: call void @llvm.assume(i1 true) [ "align"(ptr %[[A_VAL]], i64 256) ]
29+
llvm.func @_QPsimd_aligned_cptr() {
30+
%0 = llvm.mlir.constant(1 : i64) : i64
31+
%1 = llvm.alloca %0 x !llvm.struct<"_QM__fortran_builtinsT__builtin_c_ptr", (i64)> {bindc_name = "a"} : (i64) -> !llvm.ptr
32+
%2 = llvm.mlir.constant(1 : i64) : i64
33+
%3 = llvm.alloca %2 x i32 {bindc_name = "i", pinned} : (i64) -> !llvm.ptr
34+
%4 = llvm.mlir.constant(1 : i32) : i32
35+
%5 = llvm.mlir.constant(10 : i32) : i32
36+
%6 = llvm.mlir.constant(1 : i32) : i32
37+
omp.simd aligned(%1 : !llvm.ptr -> 256 : i64) {
38+
omp.loop_nest (%arg0) : i32 = (%4) to (%5) inclusive step (%6) {
39+
llvm.store %arg0, %3 : i32, !llvm.ptr
40+
omp.yield
41+
}
42+
}
43+
llvm.return
44+
}
45+
46+
//CHECK-LABEL: define void @_QPsimd_aligned_allocatable() {
47+
//CHECK: %[[A_ADDR:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }, i64 1, align 8
48+
//CHECK: %[[A_VAL:.*]] = load ptr, ptr %[[A_ADDR]], align 8
49+
//CHECK: omp_loop.preheader: ; preds = %0
50+
//CHECK: call void @llvm.assume(i1 true) [ "align"(ptr %[[A_VAL]], i64 256) ]
51+
llvm.func @_QPsimd_aligned_allocatable() {
52+
%0 = llvm.mlir.constant(1 : i64) : i64
53+
%1 = llvm.alloca %0 x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)> {bindc_name = "a"} : (i64) -> !llvm.ptr
54+
%2 = llvm.mlir.constant(1 : i32) : i32
55+
%3 = llvm.mlir.constant(10 : i32) : i32
56+
%4 = llvm.mlir.constant(1 : i32) : i32
57+
omp.simd aligned(%1 : !llvm.ptr -> 256 : i64) {
58+
omp.loop_nest (%arg0) : i32 = (%2) to (%3) inclusive step (%4) {
59+
omp.yield
60+
}
61+
}
62+
llvm.return
63+
}

0 commit comments

Comments
 (0)