[Mlir-commits] [mlir] [mlir][OpenMP] Fix update of linear iteration variables (PR #183800)
Leandro Lupori
llvmlistbot at llvm.org
Wed Mar 4 06:53:09 PST 2026
https://github.com/luporl updated https://github.com/llvm/llvm-project/pull/183800
>From e91b2f1f77cad46ec09fdce193657200a79c9c16 Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Fri, 27 Feb 2026 15:32:58 -0300
Subject: [PATCH] [mlir][OpenMP] Fix update of linear iteration variables
The final value of a linear iteration variable must be the loop
limit_value + step. Before this patch it was limit_value.
This fixes the second issue reported in #170784.
TODO add a new test and adapt the failing MLIR tests.
---
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 129 ++++++++++++------
1 file changed, 91 insertions(+), 38 deletions(-)
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 571575762d54a..389fe57f477fe 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -143,6 +143,37 @@ class LinearClauseProcessor {
llvm::BasicBlock *linearFinalizationBB;
llvm::BasicBlock *linearExitBB;
llvm::BasicBlock *linearLastIterExitBB;
+ Value linearLoopIV;
+ Value linearLoopIVStart;
+
+ void updateLinearVar(llvm::IRBuilderBase &builder, llvm::Type *varType,
+ llvm::Value *var, llvm::Value *varStart,
+ llvm::Value *step, llvm::Value *iv) {
+ if (!iv->getType()->isIntegerTy())
+ llvm_unreachable("OpenMP loop induction variable must be an integer "
+ "type");
+
+ if (varType->isIntegerTy()) {
+ // Integer path: normalize all arithmetic to linearVarType
+ iv = builder.CreateSExtOrTrunc(iv, varType);
+ step = builder.CreateSExtOrTrunc(step, varType);
+
+ llvm::Value *mulInst = builder.CreateMul(iv, step);
+ llvm::Value *addInst = builder.CreateAdd(varStart, mulInst);
+ builder.CreateStore(addInst, var);
+ } else if (varType->isFloatingPointTy()) {
+ // Float path: perform multiply in integer, then convert to float
+ step = builder.CreateSExtOrTrunc(step, iv->getType());
+
+ llvm::Value *mulInst = builder.CreateMul(iv, step);
+ llvm::Value *mulFp = builder.CreateSIToFP(mulInst, varType);
+ llvm::Value *addInst = builder.CreateFAdd(varStart, mulFp);
+ builder.CreateStore(addInst, var);
+ } else {
+ llvm_unreachable(
+ "Linear variable must be of integer or floating-point type");
+ }
+ }
public:
// Register type for the linear variables
@@ -182,46 +213,63 @@ class LinearClauseProcessor {
}
}
+ // Find linear iteration variable and save it for later updates
+ void initLinearIV(omp::SimdOp simdOp) {
+ auto loopOp = cast<omp::LoopNestOp>(simdOp.getWrappedLoop());
+ // NOTE iteration variables can only be linear in non-nested loops.
+ if (loopOp.getIVs().size() != 1)
+ return;
+ // The linear IV is the loop IV's store address.
+ BlockArgument arg = loopOp.getIVs().front();
+ for (const Operation *user : arg.getUsers()) {
+ if (auto storeOp = dyn_cast<LLVM::StoreOp>(user)) {
+ for (Value linearVar : simdOp.getLinearVars()) {
+ if (linearVar == storeOp.getAddr()) {
+ linearLoopIV = linearVar;
+ linearLoopIVStart = loopOp.getLoopLowerBounds().front();
+ break;
+ }
+ }
+ }
+ }
+ }
+
// Emit IR for updating Linear variables
- void updateLinearVar(llvm::IRBuilderBase &builder, llvm::BasicBlock *loopBody,
- llvm::Value *loopInductionVar) {
+ void updateLinearVars(llvm::IRBuilderBase &builder,
+ llvm::BasicBlock *loopBody,
+ llvm::Value *loopInductionVar) {
builder.SetInsertPoint(loopBody->getTerminator());
for (size_t index = 0; index < linearPreconditionVars.size(); index++) {
- llvm::Type *linearVarType = linearVarTypes[index];
- llvm::Value *iv = loopInductionVar;
- llvm::Value *step = linearSteps[index];
-
- if (!iv->getType()->isIntegerTy())
- llvm_unreachable("OpenMP loop induction variable must be an integer "
- "type");
-
- if (linearVarType->isIntegerTy()) {
- // Integer path: normalize all arithmetic to linearVarType
- iv = builder.CreateSExtOrTrunc(iv, linearVarType);
- step = builder.CreateSExtOrTrunc(step, linearVarType);
-
- llvm::LoadInst *linearVarStart =
- builder.CreateLoad(linearVarType, linearPreconditionVars[index]);
- llvm::Value *mulInst = builder.CreateMul(iv, step);
- llvm::Value *addInst = builder.CreateAdd(linearVarStart, mulInst);
- builder.CreateStore(addInst, linearLoopBodyTemps[index]);
- } else if (linearVarType->isFloatingPointTy()) {
- // Float path: perform multiply in integer, then convert to float
- step = builder.CreateSExtOrTrunc(step, iv->getType());
- llvm::Value *mulInst = builder.CreateMul(iv, step);
-
- llvm::LoadInst *linearVarStart =
- builder.CreateLoad(linearVarType, linearPreconditionVars[index]);
- llvm::Value *mulFp = builder.CreateSIToFP(mulInst, linearVarType);
- llvm::Value *addInst = builder.CreateFAdd(linearVarStart, mulFp);
- builder.CreateStore(addInst, linearLoopBodyTemps[index]);
- } else {
- llvm_unreachable(
- "Linear variable must be of integer or floating-point type");
- }
+ llvm::LoadInst *linearVarStart = builder.CreateLoad(
+ linearVarTypes[index], linearPreconditionVars[index]);
+ updateLinearVar(builder, linearVarTypes[index],
+ linearLoopBodyTemps[index], linearVarStart,
+ linearSteps[index], loopInductionVar);
}
}
+ // Emit IR for updating linear iteration variables on loop exit
+ void updateLinearIV(llvm::IRBuilderBase &builder,
+ LLVM::ModuleTranslation &moduleTranslation,
+ llvm::Value *loopIV) {
+ if (!linearLoopIV)
+ return;
+ llvm::Value *linearIV = moduleTranslation.lookupValue(linearLoopIV);
+ llvm::Value *linearIVStart =
+ moduleTranslation.lookupValue(linearLoopIVStart);
+
+ // Find linearIV's index
+ size_t index;
+ for (index = 0; index < linearOrigVal.size(); index++)
+ if (linearIV == linearOrigVal[index])
+ break;
+ if (index == linearOrigVal.size())
+ return;
+
+ updateLinearVar(builder, linearVarTypes[index], linearLoopBodyTemps[index],
+ linearIVStart, linearSteps[index], loopIV);
+ }
+
// Linear variable finalization is conditional on the last logical iteration.
// Create BB splits to manage the same.
void splitLinearFiniBB(llvm::IRBuilderBase &builder,
@@ -3098,8 +3146,8 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
if (failed(handleError(afterBarrierIP, *loopOp)))
return failure();
builder.restoreIP(*afterBarrierIP);
- linearClauseProcessor.updateLinearVar(builder, loopInfo->getBody(),
- loopInfo->getIndVar());
+ linearClauseProcessor.updateLinearVars(builder, loopInfo->getBody(),
+ loopInfo->getIndVar());
linearClauseProcessor.splitLinearFiniBB(builder, loopInfo->getExit());
}
@@ -3401,6 +3449,8 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
// Initialize linear variables and linear step
LinearClauseProcessor linearClauseProcessor;
+ linearClauseProcessor.initLinearIV(simdOp);
+
if (!simdOp.getLinearVars().empty()) {
auto linearVarTypes = simdOp.getLinearVarTypes().value();
for (mlir::Attribute linearVarType : linearVarTypes)
@@ -3498,8 +3548,8 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
linearClauseProcessor.initLinearVar(builder, moduleTranslation,
loopInfo->getPreheader());
- linearClauseProcessor.updateLinearVar(builder, loopInfo->getBody(),
- loopInfo->getIndVar());
+ linearClauseProcessor.updateLinearVars(builder, loopInfo->getBody(),
+ loopInfo->getIndVar());
}
builder.SetInsertPoint(*regionBlock, (*regionBlock)->begin());
@@ -3509,6 +3559,9 @@ convertOmpSimd(Operation &opInst, llvm::IRBuilderBase &builder,
: nullptr,
order, simdlen, safelen);
+ linearClauseProcessor.updateLinearIV(builder, moduleTranslation,
+ loopInfo->getIndVar());
+
linearClauseProcessor.emitStoresForLinearVar(builder);
// Check if this SIMD loop contains ordered regions
More information about the Mlir-commits
mailing list