Index: flang/test/Lower/OpenMP/simd.f90 =================================================================== --- flang/test/Lower/OpenMP/simd.f90 +++ flang/test/Lower/OpenMP/simd.f90 @@ -1,6 +1,7 @@ ! Tests for 2.9.3.1 Simd ! RUN: bbc -fopenmp -emit-fir %s -o - | FileCheck %s +! RUN: %flang_fc1 -fopenmp -emit-llvm %s -o - | FileCheck %s --check-prefixes="LLVMIR" !CHECK-LABEL: func @_QPsimdloop() subroutine simdloop @@ -28,6 +29,9 @@ ! CHECK: %[[STEP:.*]] = arith.constant 1 : i32 ! CHECK: %[[COND:.*]] = arith.cmpi sge ! CHECK: omp.simdloop if(%[[COND:.*]]) for (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) { + ! LLVMIR-LABEL: simd.if.then + ! LLVMIR-LABEL: simd.if.else + ! LLVMIR-LABEL: simd.after do i = 1, n ! CHECK: fir.store %[[I]] to %[[LOCAL:.*]] : !fir.ref ! CHECK: %[[LD:.*]] = fir.load %[[LOCAL]] : !fir.ref Index: mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp =================================================================== --- mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -898,12 +898,13 @@ return success(); } -/// Converts an OpenMP simd loop into LLVM IR using OpenMPIRBuilder. +/// Generates LLVM IR code for simd loop construct static LogicalResult -convertOmpSimdLoop(Operation &opInst, llvm::IRBuilderBase &builder, - LLVM::ModuleTranslation &moduleTranslation) { - auto loop = cast(opInst); +generateOmpSimdLoop(Operation &opInst, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation, + bool applySimd) { + auto loop = cast(opInst); llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder); // Generator of the canonical loop body. @@ -913,10 +914,6 @@ SmallVector bodyInsertPoints; LogicalResult bodyGenStatus = success(); - // TODO: The code generation for if clause is not supported yet. - if (loop.if_expr()) - return failure(); - auto bodyGen = [&](llvm::OpenMPIRBuilder::InsertPointTy ip, llvm::Value *iv) { // Make sure further conversions know about the induction variable. moduleTranslation.mapValue( @@ -970,13 +967,55 @@ llvm::IRBuilderBase::InsertPoint afterIP = loopInfos.front()->getAfterIP(); llvm::CanonicalLoopInfo *loopInfo = ompBuilder->collapseLoops(ompLoc.DL, loopInfos, {}); - - ompBuilder->applySimd(ompLoc.DL, loopInfo); + if (applySimd) + ompBuilder->applySimd(ompLoc.DL, loopInfo); builder.restoreIP(afterIP); return success(); } +/// Converts an OpenMP simd loop into LLVM IR using OpenMPIRBuilder. +static LogicalResult +convertOmpSimdLoop(Operation &opInst, llvm::IRBuilderBase &builder, + LLVM::ModuleTranslation &moduleTranslation) { + LogicalResult status = success(); + auto loop = cast(opInst); + if (loop.if_expr()) { + auto ifCond = moduleTranslation.lookupValue(loop.if_expr()); + if (ifCond) { + llvm::BasicBlock *Head = ((llvm::Instruction *)ifCond)->getParent(); + llvm::LLVMContext &C = Head->getContext(); + llvm::BasicBlock *ThenBlock = llvm::BasicBlock::Create( + C, "simd.if.then", Head->getParent(), nullptr); + llvm::BasicBlock *ElseBlock = llvm::BasicBlock::Create( + C, "simd.if.else", Head->getParent(), nullptr); + llvm::BasicBlock *AfterBlock = + llvm::BasicBlock::Create(C, "simd.after", Head->getParent(), nullptr); + builder.CreateCondBr(ifCond, ThenBlock, ElseBlock); + builder.SetInsertPoint(ThenBlock); + status = generateOmpSimdLoop(opInst, builder, moduleTranslation, + /* apply SIMD */ true); + if (failed(status)) + return failure(); + + builder.CreateBr(AfterBlock); + builder.SetInsertPoint(ElseBlock); + status = generateOmpSimdLoop(opInst, builder, moduleTranslation, + /* apply SIMD */ false); + if (failed(status)) + return failure(); + + builder.CreateBr(AfterBlock); + builder.SetInsertPoint(AfterBlock); + } else + return failure(); + } else + status = generateOmpSimdLoop(opInst, builder, moduleTranslation, + /* apply SIMD */ true); + + return status; +} + /// Convert an Atomic Ordering attribute to llvm::AtomicOrdering. llvm::AtomicOrdering convertAtomicOrdering(Optional ao) {