[flang-commits] [flang] [llvm] [mlir] [openmp] [Flang][OpenMP] Lower scan directive and inscan reduction modifier (PR #206747)
via flang-commits
flang-commits at lists.llvm.org
Tue Jul 28 12:51:56 PDT 2026
================
@@ -5489,17 +5525,56 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::emitScanReduction(
ScanRedInfo->Span,
llvm::ConstantInt::get(ScanRedInfo->Span->getType(), 1));
Builder.SetInsertPoint(InputBB);
- Builder.CreateBr(LoopBB);
+ // Combine the original variable's incoming value (orig-val) into the first
+ // buffer element before computing the prefix sum. Per the OpenMP scan
+ // semantics orig-val is a single prefix element that must be reflected in
+ // every inclusive/exclusive scan result and in the final reduction value.
+ // Folding it in here lets the log-scan prefix computation propagate it into
+ // every element (and into the finals' read of `buffer[Span]`), regardless
+ // of whether an iteration's input phase accumulates into or overwrites the
+ // reduction variable. `select(Span > 0, 1, 0)` keeps the access in bounds
+ // when Span == 0: buffer[0] is otherwise unused and the finals' zero-trip
+ // guard discards it.
+ llvm::Value *HasElem = Builder.CreateICmpUGT(
+ ScanRedInfo->Span, llvm::ConstantInt::get(IndexTy, 0));
+ llvm::Value *FirstIdx =
+ Builder.CreateSelect(HasElem, llvm::ConstantInt::get(IndexTy, 1),
+ llvm::ConstantInt::get(IndexTy, 0));
+ for (ReductionInfo RedInfo : ReductionInfos) {
+ Value *ReductionVal = RedInfo.PrivateVariable;
+ Value *BuffPtr = (*(ScanRedInfo->ScanBuffPtrs))[ReductionVal];
+ Value *Buff = Builder.CreateLoad(Builder.getPtrTy(), BuffPtr);
+ Type *DestTy = RedInfo.ElementType;
+ Value *ElemPtr =
+ Builder.CreateInBoundsGEP(DestTy, Buff, FirstIdx, "arrayOffset");
+ Value *OrigVal = Builder.CreateLoad(DestTy, RedInfo.Variable);
+ Value *Elem = Builder.CreateLoad(DestTy, ElemPtr);
----------------
chichunchen wrote:
When the loop has zero logical iterations, no scan-buffer entry is populated. This load nevertheless reads the uninitialized buffer[0], which is then passed to the reduction combiner before the trip count
is checked.
The final result often appears correct because a later select preserves orig-val, but an input-sensitive user-defined combiner can still trigger undefined behavior. Could we branch around the seed load and combination when Span == 0?
https://github.com/llvm/llvm-project/pull/206747
More information about the flang-commits
mailing list