From 1bd63928e4fcf575d93aaef220c19ca41965e015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Susan=20Tan=20=28=E3=82=B9-=E3=82=B6=E3=83=B3=E3=80=80?= =?UTF-8?q?=E3=82=BF=E3=83=B3=29?= Date: Thu, 9 Jul 2026 14:46:53 -0400 Subject: [PATCH 001/125] [flang][acc] Add `OutlineIdentityOperandOpInterface` to hlfir/fir declare (#208091) Inlining can leave a `fir.declare`'s dummy_scope operand (`!fir.dscope`) defined outside an OpenACC compute region while the declare itself gets rematerialized inside, since `fir.dummy_scope` wasn't registered as an OutlineRematerializationOpInterface candidate. This dangling, unmappable live-in is illegal for parallelization. Fix: Added `OutlineIdentityOperandOpInterface`, implemented by `fir.declare/hlfir.declare`, so `OffloadLiveInValueCanonicalization` drops their dummy_scope operand (an identity token that must never be duplicated) instead of cloning it when sinking/rematerializing them into offload regions. --- .../OpenACC/Support/FIROpenACCOpsInterfaces.h | 14 ++++ .../Support/FIROpenACCOpsInterfaces.cpp | 20 ++++++ .../Support/RegisterOpenACCExtensions.cpp | 4 ++ .../offload-livein-value-canonicalization.fir | 72 +++++++++++++++++++ .../Dialect/OpenACC/OpenACCOpsInterfaces.td | 22 ++++++ .../OffloadLiveInValueCanonicalization.cpp | 15 ++++ 6 files changed, 147 insertions(+) diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h index a39d517412c07..31e1593e11325 100644 --- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h +++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.h @@ -99,6 +99,20 @@ struct OutlineRematerializationModel bool isRematerializationCandidate(mlir::Operation *op) const; }; +/// External model for OutlineIdentityOperandOpInterface. +/// Drops the dummy_scope operand (an identity token that must not be +/// duplicated) from a [hl]fir.declare instance that has been sunk or +/// rematerialized into an offload region. Alias analysis falls back to a +/// dominance-based lookup of the enclosing dummy scope when this operand is +/// absent, so correctness is preserved without needing to keep or clone the +/// original operand. +template +struct OutlineIdentityOperandDeclareModel + : public mlir::acc::OutlineIdentityOperandOpInterface::ExternalModel< + OutlineIdentityOperandDeclareModel, Op> { + void dropOutlinedIdentityOperands(mlir::Operation *op) const; +}; + /// External model for OffloadRegionOpInterface. /// This interface marks operations whose regions are targets for offloading /// and outlining. diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp index 590619a31a33f..8e4b55fe5f4a8 100644 --- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCOpsInterfaces.cpp @@ -143,6 +143,26 @@ bool OutlineRematerializationModel< fir::ConvertOp::isIntegerCompatible(outTy); } +template <> +void OutlineIdentityOperandDeclareModel< + fir::DeclareOp>::dropOutlinedIdentityOperands(mlir::Operation *op) const { + auto declareOp = mlir::cast(op); + if (declareOp.getDummyScope()) { + declareOp.getDummyScopeMutable().clear(); + declareOp->removeAttr(declareOp.getDummyArgNoAttrName()); + } +} + +template <> +void OutlineIdentityOperandDeclareModel< + hlfir::DeclareOp>::dropOutlinedIdentityOperands(mlir::Operation *op) const { + auto declareOp = mlir::cast(op); + if (declareOp.getDummyScope()) { + declareOp.getDummyScopeMutable().clear(); + declareOp->removeAttr(declareOp.getDummyArgNoAttrName()); + } +} + // Helper to recursively process address-of operations in derived type // descriptors and collect all needed fir.globals. static void processAddrOfOpInDerivedTypeDescriptor( diff --git a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp index 070208d22ba05..7e5eeda1f5de9 100644 --- a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp @@ -53,6 +53,8 @@ void registerOpenACCExtensions(mlir::DialectRegistry ®istry) { PartialEntityAccessModel>(*ctx); fir::DeclareOp::attachInterface>( *ctx); + fir::DeclareOp::attachInterface< + OutlineIdentityOperandDeclareModel>(*ctx); fir::AddrOfOp::attachInterface(*ctx); fir::GlobalOp::attachInterface(*ctx); @@ -94,6 +96,8 @@ void registerOpenACCExtensions(mlir::DialectRegistry ®istry) { PartialEntityAccessModel>(*ctx); hlfir::DeclareOp::attachInterface< PartialEntityAccessModel>(*ctx); + hlfir::DeclareOp::attachInterface< + OutlineIdentityOperandDeclareModel>(*ctx); }); // Register CUF operation interfaces diff --git a/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir b/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir index e692e5fb6dc4f..8b1d4cd0b1e16 100644 --- a/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir +++ b/flang/test/Fir/OpenACC/offload-livein-value-canonicalization.fir @@ -467,3 +467,75 @@ func.func @test_undef_slice_rematerialize(%arg0: !fir.box>) // CHECK: %[[UNDEF_INNER:.*]] = fir.undefined index // CHECK: %[[SLICE_INNER:.*]] = fir.slice {{.*}}, %[[UNDEF_INNER]], %[[UNDEF_INNER]] // CHECK: fir.rebox %arg0 [%[[SLICE_INNER]]] + +// ----- + +// Test that fir.declare's dummy_scope operand is dropped, not duplicated, +// when the declare is sunk into an offload region. Regression test: after +// inlining, a fir.declare for a dummy argument aliasing a device-valid +// global (e.g. one with !$ACC DECLARE COPYIN) is sunk/rematerialized into +// the offload region. Its dummy_scope operand is an identity token (see +// fir.dummy_scope) that must never be duplicated, so it must be dropped +// from the sunk/cloned declare instead of being left as an illegal live-in +// or cloned alongside it. + +fir.global @global_for_dummy_scope {acc.declare = #acc.declare} : i32 { + %0 = arith.constant 0 : i32 + fir.has_value %0 : i32 +} + +func.func private @use_ref(!fir.ref) -> () + +func.func @test_dummy_scope_sink() { + %addr = fir.address_of(@global_for_dummy_scope) : !fir.ref + %scope = fir.dummy_scope : !fir.dscope + %decl = fir.declare %addr dummy_scope %scope {uniq_name = "global"} : (!fir.ref, !fir.dscope) -> !fir.ref + acc.serial { + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.yield + } + return +} + +// CHECK-LABEL: @test_dummy_scope_sink +// The dummy scope stays outside, untouched and unduplicated: nothing +// references it anymore once the declare's operand is dropped. +// CHECK: fir.dummy_scope +// CHECK: acc.serial { +// CHECK-DAG: fir.address_of(@global_for_dummy_scope) +// CHECK-DAG: %[[DECL:.*]] = fir.declare %{{.*}} {uniq_name = "global"} : (!fir.ref) -> !fir.ref +// CHECK: fir.call @use_ref(%[[DECL]]) + +// ----- + +// Test fir.declare rematerialization (used both inside and outside region): +// the outer declare keeps its dummy_scope untouched, while the clone made +// for the region drops it rather than duplicating the scope. + +fir.global @global_for_dummy_scope_remat {acc.declare = #acc.declare} : i32 { + %0 = arith.constant 0 : i32 + fir.has_value %0 : i32 +} + +func.func private @use_ref(!fir.ref) -> () + +func.func @test_dummy_scope_rematerialize() { + %addr = fir.address_of(@global_for_dummy_scope_remat) : !fir.ref + %scope = fir.dummy_scope : !fir.dscope + %decl = fir.declare %addr dummy_scope %scope {uniq_name = "global"} : (!fir.ref, !fir.dscope) -> !fir.ref + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.serial { + fir.call @use_ref(%decl) : (!fir.ref) -> () + acc.yield + } + return +} + +// CHECK-LABEL: @test_dummy_scope_rematerialize +// CHECK: %[[SCOPE:.*]] = fir.dummy_scope +// CHECK: %[[DECL_OUTER:.*]] = fir.declare %{{.*}} dummy_scope %[[SCOPE]] {uniq_name = "global"} +// CHECK: fir.call @use_ref(%[[DECL_OUTER]]) +// CHECK: acc.serial { +// CHECK-DAG: fir.address_of(@global_for_dummy_scope_remat) +// CHECK-DAG: %[[DECL_INNER:.*]] = fir.declare %{{.*}} {uniq_name = "global"} : (!fir.ref) -> !fir.ref +// CHECK: fir.call @use_ref(%[[DECL_INNER]]) diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td index a42bb7a66aae7..fa44fe7a49158 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td @@ -141,6 +141,28 @@ def OutlineRematerializationOpInterface : OpInterface<"OutlineRematerializationO }]; } +def OutlineIdentityOperandOpInterface + : OpInterface<"OutlineIdentityOperandOpInterface"> { + let cppNamespace = "::mlir::acc"; + + let description = [{ + An interface for operations with an "identity" operand (e.g. FIR's + dummy scope handle) that must never be duplicated, unlike operands + handled by `OutlineRematerializationOpInterface`. When such an + operation is sunk/cloned into an offload region and the operand would + otherwise reference a value outside it, drop the operand instead of + cloning it; implementations must preserve correctness some other way + (e.g. FIR's dominance-based scope lookup fallback). + }]; + + let methods = [ + InterfaceMethod<"Drop any identity operands from this operation " + "instance that reference values defined outside its " + "containing region.", + "void", "dropOutlinedIdentityOperands", (ins), [{}]>, + ]; +} + def OffloadRegionOpInterface : OpInterface<"OffloadRegionOpInterface"> { let cppNamespace = "::mlir::acc"; diff --git a/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp b/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp index 60285c8a02bb9..4b57354b8b5d8 100644 --- a/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp +++ b/mlir/lib/Dialect/OpenACC/Transforms/OffloadLiveInValueCanonicalization.cpp @@ -246,6 +246,13 @@ class OffloadLiveInValueCanonicalization Operation *sinkOp = sinkCandidate.getDefiningOp(); assert(sinkOp && "must have op to be considered"); sinkOp->moveBefore(®ion.front().front()); + // Some operations (e.g. fir.declare) may carry identity operands that + // must not be left referencing a value defined outside the region. + // Unlike other operands, such identity operands cannot simply be + // treated as new live-ins to legalize; they must be dropped instead. + if (auto identityOp = + dyn_cast(sinkOp)) + identityOp.dropOutlinedIdentityOperands(); LLVM_DEBUG(llvm::dbgs() << "\t\tSunk: " << *sinkOp << "\n"); } @@ -262,6 +269,14 @@ class OffloadLiveInValueCanonicalization computeTopologicalSorting(opsToRematerialize); for (Operation *rematerializationOp : opsToRematerialize) { Operation *clonedOp = builder.clone(*rematerializationOp); + // See the comment above: identity operands must be dropped from the + // clone rather than duplicated, since duplicating them would make the + // clone appear to belong to a different instantiation than the + // original operation (and any of its siblings left outside the + // region). + if (auto identityOp = + dyn_cast(clonedOp)) + identityOp.dropOutlinedIdentityOperands(); for (auto [oldResult, newResult] : llvm::zip( rematerializationOp->getResults(), clonedOp->getResults())) { replaceAllUsesInRegionWith(oldResult, newResult, region); From 8e0712496c891b8532157156ecacce3e5af89e26 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Thu, 9 Jul 2026 20:49:21 +0200 Subject: [PATCH 002/125] [InstCombine] Use constant 64-bit indices for CreateExtractElement (NFC) (#208306) The canonical form preferred by instCombine is to use 64-bit values for the index when it is a constant for ExtractElement. --- llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 4 +--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index f630d1efbd7e7..f30a7b5e891ab 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -3416,9 +3416,7 @@ Instruction *InstCombinerImpl::visitBitCast(BitCastInst &CI) { // If our destination is not a vector, then make this a straight // scalar-scalar cast. if (!DestTy->isVectorTy()) { - Value *Elem = - Builder.CreateExtractElement(Src, - Constant::getNullValue(Type::getInt32Ty(CI.getContext()))); + Value *Elem = Builder.CreateExtractElement(Src, uint64_t{0}); return CastInst::Create(Instruction::BitCast, Elem, DestTy); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index e6deb548819e8..42c2983034e22 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3569,10 +3569,9 @@ Instruction *InstCombinerImpl::foldICmpBitCast(ICmpInst &Cmp) { // Fold the icmp based on the value of C // If C is M copies of an iK sized bit pattern, // then: - // => %E = extractelement %vec, i32 Elem + // => %E = extractelement %vec, i64 Elem // icmp iK %SplatVal, - Value *Elem = Builder.getInt32(Mask[0]); - Value *Extract = Builder.CreateExtractElement(Vec, Elem); + Value *Extract = Builder.CreateExtractElement(Vec, Mask[0]); Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth())); return new ICmpInst(Pred, Extract, NewC); } From 4aba9d237a1ad07751fff354a56f4f2cf9dfecfe Mon Sep 17 00:00:00 2001 From: Luke Hutton Date: Thu, 9 Jul 2026 19:49:44 +0100 Subject: [PATCH 003/125] [mlir][tosa] Fold tiled input into binary elementwise operations (#203941) Canonicalizes explicit broadcasting into implicit broadcasting by folding the tile input into the binary element-wise operation. --- mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td | 1 + .../Dialect/Tosa/IR/TosaCanonicalizations.cpp | 78 +++++++++ mlir/test/Dialect/Tosa/canonicalize.mlir | 160 ++++++++++++++++++ 3 files changed, 239 insertions(+) diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td index 5e5760e33b5f6..e3b74f5a07d3f 100644 --- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td +++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td @@ -2485,6 +2485,7 @@ def Tosa_TileOp : Tosa_InferShapedTypeOp<"tile", [Pure]> { LogicalResult getConstantMultiples(llvm::SmallVector &multiples); }]; + let hasCanonicalizer = 1; let hasFolder = 1; let hasVerifier = 1; diff --git a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp index 4c98aca0ee8d7..19f35757bdd83 100644 --- a/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp +++ b/mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp @@ -20,8 +20,10 @@ #include "mlir/Dialect/Traits.h" #include "mlir/IR/BuiltinTypeInterfaces.h" #include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/IRMapping.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/PatternMatch.h" +#include "mlir/IR/TypeUtilities.h" #include "mlir/Transforms/FoldUtils.h" #include "mlir/Transforms/InliningUtils.h" #include "llvm/ADT/APFloat.h" @@ -2326,6 +2328,82 @@ OpFoldResult tosa::SelectOp::fold(FoldAdaptor adaptor) { return {}; } +static LogicalResult verifyTileIsBroadcast(tosa::TileOp tileOp) { + const auto inputType = + dyn_cast(tileOp.getInput1().getType()); + const auto outputType = dyn_cast(tileOp.getType()); + if (!inputType || !outputType) + return failure(); + + SmallVector multiples; + if (failed(tileOp.getConstantMultiples(multiples))) + return failure(); + + for (const auto [index, multiple] : llvm::enumerate(multiples)) { + if (multiple == 1) + continue; + if (outputType.isDynamicDim(index)) + return failure(); + if (inputType.getDimSize(index) != 1) + return failure(); + } + + return success(); +} + +struct RemoveBroadcastTileFromBinaryElementwise + : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(tosa::TileOp tileOp, + PatternRewriter &rewriter) const override { + Value tileOutput = tileOp.getOutput(); + if (!tileOutput.hasOneUse()) + return rewriter.notifyMatchFailure(tileOp, + "tile output must have one use"); + + Operation *user = *tileOutput.user_begin(); + const bool isBinaryElementwise = + user->getNumOperands() == 2 && + user->hasTrait(); + if (!isBinaryElementwise && !isa(user)) + return rewriter.notifyMatchFailure( + tileOp, "consumer must be binary broadcastable"); + + if (failed(verifyTileIsBroadcast(tileOp))) + return rewriter.notifyMatchFailure( + tileOp, "tile must only expand statically-known singleton dims"); + + Value lhsOperand = user->getOperand(0); + Value rhsOperand = user->getOperand(1); + Value otherOperand = lhsOperand == tileOutput ? rhsOperand : lhsOperand; + Value tileInput = tileOp.getInput1(); + + const ShapedType newOtherType = cast(otherOperand.getType()); + const ShapedType newTileType = cast(tileInput.getType()); + SmallVector broadcastedShape; + OpTrait::util::getBroadcastedShape( + newOtherType.getShape(), newTileType.getShape(), broadcastedShape); + + const ShapedType outputType = cast(user->getResultTypes()[0]); + if (!llvm::equal(broadcastedShape, outputType.getShape())) + return rewriter.notifyMatchFailure( + tileOp, "tile output must be broadcastable to consumer operands"); + + rewriter.setInsertionPoint(user); + IRMapping mapper; + mapper.map(tileOutput, tileOp.getInput1()); + Operation *newUser = rewriter.clone(*user, mapper); + rewriter.replaceOp(user, newUser->getResults()); + return success(); + } +}; + +void TileOp::getCanonicalizationPatterns(RewritePatternSet &results, + MLIRContext *context) { + results.add(context); +} + OpFoldResult TileOp::fold(FoldAdaptor adaptor) { if (getInput1().getType() == getType()) { if (auto multiples = llvm::dyn_cast_if_present( diff --git a/mlir/test/Dialect/Tosa/canonicalize.mlir b/mlir/test/Dialect/Tosa/canonicalize.mlir index 6a3d84e8d133b..585589ac1405a 100644 --- a/mlir/test/Dialect/Tosa/canonicalize.mlir +++ b/mlir/test/Dialect/Tosa/canonicalize.mlir @@ -1996,6 +1996,166 @@ func.func @dont_canonicalize_non_const_avg_pool2d_adaptive(%arg0: tensor<1x?x?x8 // ----- +// CHECK-LABEL: @canonicalize_tile_broadcast_sub +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<96x56x56x96xf32>, %[[ARG1:[^:]+]]: tensor<1x56x56x1xf32> +// CHECK-NOT: tosa.tile +// CHECK: %[[SUB:.+]] = tosa.sub %[[ARG0]], %[[ARG1]] : (tensor<96x56x56x96xf32>, tensor<1x56x56x1xf32>) -> tensor<96x56x56x96xf32> +// CHECK: return %[[SUB]] +func.func @canonicalize_tile_broadcast_sub(%arg0: tensor<96x56x56x96xf32>, %arg1: tensor<1x56x56x1xf32>) -> tensor<96x56x56x96xf32> { + %shape = tosa.const_shape {values = dense<[96, 1, 1, 96]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x1xf32>, !tosa.shape<4>) -> tensor<96x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<96x56x56x96xf32>, tensor<96x56x56x96xf32>) -> tensor<96x56x56x96xf32> + return %sub : tensor<96x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @canonicalize_tile_broadcast_greater +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<1x197x768xf32>, %[[ARG1:[^:]+]]: tensor<1x197x1xf32> +// CHECK-NOT: tosa.tile +// CHECK: %[[GT:.+]] = tosa.greater %[[ARG0]], %[[ARG1]] : (tensor<1x197x768xf32>, tensor<1x197x1xf32>) -> tensor<1x197x768xi1> +// CHECK: return %[[GT]] +func.func @canonicalize_tile_broadcast_greater(%arg0: tensor<1x197x768xf32>, %arg1: tensor<1x197x1xf32>) -> tensor<1x197x768xi1> { + %shape = tosa.const_shape {values = dense<[1, 1, 768]> : tensor<3xindex>} : () -> !tosa.shape<3> + %tile = tosa.tile %arg1, %shape : (tensor<1x197x1xf32>, !tosa.shape<3>) -> tensor<1x197x768xf32> + %gt = tosa.greater %arg0, %tile : (tensor<1x197x768xf32>, tensor<1x197x768xf32>) -> tensor<1x197x768xi1> + return %gt : tensor<1x197x768xi1> +} + +// ----- + +// CHECK-LABEL: @canonicalize_tile_broadcast_mul +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<1x197x768xf32>, %[[ARG1:[^:]+]]: tensor<1x197x1xf32>, %[[SHIFT:[^:]+]]: tensor<1xi8> +// CHECK-NOT: tosa.tile +// CHECK: %[[MUL:.+]] = tosa.mul %[[ARG0]], %[[ARG1]], %[[SHIFT]] : (tensor<1x197x768xf32>, tensor<1x197x1xf32>, tensor<1xi8>) -> tensor<1x197x768xf32> +// CHECK: return %[[MUL]] +func.func @canonicalize_tile_broadcast_mul(%arg0: tensor<1x197x768xf32>, %arg1: tensor<1x197x1xf32>, %shift: tensor<1xi8>) -> tensor<1x197x768xf32> { + %shape = tosa.const_shape {values = dense<[1, 1, 768]> : tensor<3xindex>} : () -> !tosa.shape<3> + %tile = tosa.tile %arg1, %shape : (tensor<1x197x1xf32>, !tosa.shape<3>) -> tensor<1x197x768xf32> + %mul = tosa.mul %arg0, %tile, %shift : (tensor<1x197x768xf32>, tensor<1x197x768xf32>, tensor<1xi8>) -> tensor<1x197x768xf32> + return %mul : tensor<1x197x768xf32> +} + + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_when_result_no_longer_broadcastable +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_when_result_no_longer_broadcastable(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %tile, %arg0 : (tensor<2x4xf32>, tensor<2x1xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_second_tile_when_result_no_longer_broadcastable +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<2x1xf32> +// CHECK: %[[SHAPE:.+]] = tosa.const_shape +// CHECK: %[[TILE:.+]] = tosa.tile %[[ARG0]], %[[SHAPE]] +// CHECK: %[[ADD:.+]] = tosa.add %[[ARG0]], %[[TILE]] : (tensor<2x1xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> +// CHECK: return %[[ADD]] +func.func @dont_canonicalize_second_tile_when_result_no_longer_broadcastable(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile0 = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %tile1 = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %add = tosa.add %tile0, %tile1 : (tensor<2x4xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %add : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_with_unranked_other_operand +// CHECK-SAME: %[[ARG0:[^:]+]]: tensor<2x1xf32>, %[[ARG1:[^:]+]]: tensor<*xf32> +// CHECK: %[[SHAPE:.+]] = tosa.const_shape +// CHECK: %[[TILE:.+]] = tosa.tile %[[ARG0]], %[[SHAPE]] +// CHECK: %[[SUB:.+]] = tosa.sub %[[ARG1]], %[[TILE]] : (tensor<*xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> +// CHECK: return %[[SUB]] +func.func @dont_canonicalize_tile_with_unranked_other_operand(%arg0: tensor<2x1xf32>, %arg1: tensor<*xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %arg1, %tile : (tensor<*xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_non_singleton_expansion +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_non_singleton_expansion(%arg0: tensor<1x56x56x96xf32>, %arg1: tensor<1x56x56x2xf32>) -> tensor<1x56x56x96xf32> { + %shape = tosa.const_shape {values = dense<[1, 1, 1, 48]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x2xf32>, !tosa.shape<4>) -> tensor<1x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + return %sub : tensor<1x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_dynamic_expanded_dim +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_dynamic_expanded_dim(%arg0: tensor<2x?xf32>, %arg1: tensor<2x4xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x?xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %sub = tosa.sub %arg1, %tile : (tensor<2x4xf32>, tensor<2x4xf32>) -> tensor<2x4xf32> + return %sub : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_dynamic_output +// CHECK: tosa.tile +// CHECK: tosa.sub +func.func @dont_canonicalize_tile_dynamic_output(%arg0: tensor<2x?xf32>, %arg1: tensor<2x1xf32>) -> tensor<2x?xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg1, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x?xf32> + %sub = tosa.sub %arg0, %tile : (tensor<2x?xf32>, tensor<2x?xf32>) -> tensor<2x?xf32> + return %sub : tensor<2x?xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_multi_use +// CHECK: tosa.tile +// CHECK: tosa.sub +// CHECK: tosa.add +func.func @dont_canonicalize_tile_multi_use(%arg0: tensor<1x56x56x96xf32>, %arg1: tensor<1x56x56x1xf32>) -> (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) { + %shape = tosa.const_shape {values = dense<[1, 1, 1, 96]> : tensor<4xindex>} : () -> !tosa.shape<4> + %tile = tosa.tile %arg1, %shape : (tensor<1x56x56x1xf32>, !tosa.shape<4>) -> tensor<1x56x56x96xf32> + %sub = tosa.sub %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + %add = tosa.add %arg0, %tile : (tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32>) -> tensor<1x56x56x96xf32> + return %sub, %add : tensor<1x56x56x96xf32>, tensor<1x56x56x96xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_unary_elementwise +// CHECK: tosa.tile +// CHECK: tosa.abs +func.func @dont_canonicalize_tile_unary_elementwise(%arg0: tensor<2x1xf32>) -> tensor<2x4xf32> { + %shape = tosa.const_shape {values = dense<[1, 4]> : tensor<2xindex>} : () -> !tosa.shape<2> + %tile = tosa.tile %arg0, %shape : (tensor<2x1xf32>, !tosa.shape<2>) -> tensor<2x4xf32> + %abs = tosa.abs %tile : (tensor<2x4xf32>) -> tensor<2x4xf32> + return %abs : tensor<2x4xf32> +} + +// ----- + +// CHECK-LABEL: @dont_canonicalize_tile_used_as_mul_shift +// CHECK: tosa.tile +// CHECK: tosa.mul +func.func @dont_canonicalize_tile_used_as_mul_shift(%lhs: tensor<1xf32>, %rhs: tensor<1xf32>, %shift: tensor) -> tensor<1xf32> { + %multiples = tosa.const_shape {values = dense<[1]> : tensor<1xindex>} : () -> !tosa.shape<1> + %shift_static = tosa.tile %shift, %multiples : (tensor, !tosa.shape<1>) -> tensor<1xi8> + %mul = tosa.mul %lhs, %rhs, %shift_static : (tensor<1xf32>, tensor<1xf32>, tensor<1xi8>) -> tensor<1xf32> + return %mul : tensor<1xf32> +} + +// ----- + // CHECK-LABEL: test_single_concat // CHECK: %[[VAL_1:.*]] = tosa.concat %arg0, %arg0 {axis = 1 : i32} : (tensor<1x1x7x7xf32>, tensor<1x1x7x7xf32>) -> tensor<1x2x7x7xf32> // CHECK: return %[[VAL_1]] : tensor<1x2x7x7xf32> From 5114f5e4269bd7b189b1500889cd88d0d1eff033 Mon Sep 17 00:00:00 2001 From: Kyungtak Woo Date: Thu, 9 Jul 2026 12:58:50 -0600 Subject: [PATCH 004/125] [Clang][Sema] Ensure explicitly defaulted functions respect FP pragmas from their declaration site (#207429) Currently, when an explicitly defaulted function is synthesized (e.g., at its first use), it erroneously adopts the floating-point (FP) pragma state of the synthesis site rather than its declaration site. This leads to mismatched or incorrect FP features being applied to the generated body, completely ignoring `#pragma STDC FENV_ACCESS` pragmas that were active when the function was explicitly defaulted. This change should fix this issue by capturing and restoring the FP features at the appropriate times. Fixes #207266 I also added the following fixes to support the above: - AST Importer Fix: Updated ASTImporter::VisitFunctionDecl to correctly import FPFeatures and Lookups for defaulted/deleted functions, whereas before it was silently dropping them. - AST Version Bump: Bumped VERSION_MAJOR to 39 in ASTBitCodes.h to reflect the new FunctionDecl binary layout changes in the AST serialization. --- clang/include/clang/AST/Decl.h | 9 +- clang/include/clang/Basic/LangOptions.h | 4 + .../include/clang/Serialization/ASTBitCodes.h | 2 +- clang/lib/AST/ASTImporter.cpp | 30 ++++-- clang/lib/AST/Decl.cpp | 5 +- clang/lib/Sema/SemaDeclCXX.cpp | 39 ++++++- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 +- clang/lib/Serialization/ASTReaderDecl.cpp | 5 +- clang/lib/Serialization/ASTWriterDecl.cpp | 2 + .../defaulted-function-fp-features.cpp | 101 ++++++++++++++++++ 10 files changed, 184 insertions(+), 18 deletions(-) create mode 100644 clang/test/CodeGenCXX/defaulted-function-fp-features.cpp diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 88c900203630a..a6e9b3bcaa608 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2049,13 +2049,17 @@ class FunctionDecl : public DeclaratorDecl, }; - /// Stashed information about a defaulted/deleted function body. + /// Stashed information about a defaulted/deleted function body, including + /// the active FP pragma overrides (FPOptionsOverride) from the declaration + /// site. These overrides are required to correctly synthesize the function + /// body. class DefaultedOrDeletedFunctionInfo final : llvm::TrailingObjects { friend TrailingObjects; unsigned NumLookups; bool HasDeletedMessage; + FPOptionsOverride FPFeatures; size_t numTrailingObjects(OverloadToken) const { return NumLookups; @@ -2064,8 +2068,11 @@ class FunctionDecl : public DeclaratorDecl, public: static DefaultedOrDeletedFunctionInfo * Create(ASTContext &Context, ArrayRef Lookups, + FPOptionsOverride FPFeatures, StringLiteral *DeletedMessage = nullptr); + FPOptionsOverride getFPFeatures() const { return FPFeatures; } + /// Get the unqualified lookup results that should be used in this /// defaulted function definition. ArrayRef getUnqualifiedLookups() const { diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 6c86300fc5581..f21131622d03d 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -989,6 +989,10 @@ class FPOptions { /// /// The is implemented as a value of the new FPOptions plus a mask showing which /// fields are actually set in it. +/// +/// NOTE: This type is serialized into the AST format (e.g. for defaulted +/// functions). When adding a new field here or in FPOptions, ensure that the +/// AST VERSION_MAJOR is bumped if it changes the layout or size. class FPOptionsOverride { FPOptions Options = FPOptions::getFromOpaqueInt(0); FPOptions::storage_type OverrideMask = 0; diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 279380de2f7fe..73388948b5750 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -44,7 +44,7 @@ namespace serialization { /// Version 4 of AST files also requires that the version control branch and /// revision match exactly, since there is no backward compatibility of /// AST files at this time. -const unsigned VERSION_MAJOR = 38; +const unsigned VERSION_MAJOR = 39; /// AST file minor version number supported by this version of /// Clang. diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 64e9b7aebd1d1..d1de2dbac2a0e 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -4246,13 +4246,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { // decl and its redeclarations may be required. } - StringLiteral *Msg = D->getDeletedMessage(); - if (Msg) { - auto Imported = import(Msg); - if (!Imported) - return Imported.takeError(); - Msg = *Imported; - } + // We will import DefaultedOrDeletedInfo later. ToFunction->setQualifierInfo(ToQualifierLoc); ToFunction->setAccess(D->getAccess()); @@ -4271,10 +4265,28 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { ToFunction->setRangeEnd(ToEndLoc); ToFunction->setDefaultLoc(ToDefaultLoc); - if (Msg) + if (auto *Info = D->getDefaultedOrDeletedInfo()) { + StringLiteral *Msg = nullptr; + if (StringLiteral *M = Info->getDeletedMessage()) { + auto Imported = import(M); + if (!Imported) + return Imported.takeError(); + Msg = *Imported; + } + + SmallVector Lookups; + for (DeclAccessPair P : Info->getUnqualifiedLookups()) { + auto Imported = import(P.getDecl()); + if (!Imported) + return Imported.takeError(); + Lookups.push_back( + DeclAccessPair::make(cast(*Imported), P.getAccess())); + } + ToFunction->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Importer.getToContext(), {}, Msg)); + Importer.getToContext(), Lookups, Info->getFPFeatures(), Msg)); + } // Set the parameters. for (auto *Param : Parameters) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index b23bf73ae803c..4eaef0d87f3e5 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3116,7 +3116,7 @@ bool FunctionDecl::isVariadic() const { FunctionDecl::DefaultedOrDeletedFunctionInfo * FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( ASTContext &Context, ArrayRef Lookups, - StringLiteral *DeletedMessage) { + FPOptionsOverride FPFeatures, StringLiteral *DeletedMessage) { static constexpr size_t Alignment = std::max({alignof(DefaultedOrDeletedFunctionInfo), alignof(DeclAccessPair), alignof(StringLiteral *)}); @@ -3127,6 +3127,7 @@ FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( new (Context.Allocate(Size, Alignment)) DefaultedOrDeletedFunctionInfo; Info->NumLookups = Lookups.size(); Info->HasDeletedMessage = DeletedMessage != nullptr; + Info->FPFeatures = FPFeatures; llvm::uninitialized_copy(Lookups, Info->getTrailingObjects()); if (DeletedMessage) @@ -3152,7 +3153,7 @@ void FunctionDecl::setDeletedAsWritten(bool D, StringLiteral *Message) { DefaultedOrDeletedInfo->setDeletedMessage(Message); else setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo::Create( - getASTContext(), /*Lookups=*/{}, Message)); + getASTContext(), /*Lookups=*/{}, FPOptionsOverride(), Message)); } } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 65b46562b166e..15c3b04942825 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6906,6 +6906,25 @@ Sema::getDefaultedFunctionKind(const FunctionDecl *FD) { return DefaultedFunctionKind(); } +namespace { +/// RAII object to restore the floating-point (FP) features active at the time +/// a defaulted function was declared. This ensures that the synthesized body +/// of the function respects the FP pragmas (e.g., #pragma STDC FENV_ACCESS) +/// that were in effect when the function was explicitly defaulted. +struct DefaultedFunctionFPFeaturesRAII { + Sema::FPFeaturesStateRAII SavedFPFeatures; + DefaultedFunctionFPFeaturesRAII(Sema &S, FunctionDecl *FD) + : SavedFPFeatures(S) { + auto *Info = FD->getDefaultedOrDeletedInfo(); + FPOptionsOverride FPO = Info ? Info->getFPFeatures() : FPOptionsOverride(); + S.CurFPFeatures = FPO.applyOverrides(S.LangOpts); + S.FpPragmaStack.CurrentValue = FPO; + } + + ~DefaultedFunctionFPFeaturesRAII() = default; +}; +} // namespace + static void DefineDefaultedFunction(Sema &S, FunctionDecl *FD, SourceLocation DefaultLoc) { Sema::DefaultedFunctionKind DFK = S.getDefaultedFunctionKind(FD); @@ -9029,7 +9048,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD, FD->getOverloadedOperator()); FD->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Context, Operators.pairs())); + Context, Operators.pairs(), CurFPFeatureOverrides())); } // C++2a [class.compare.default]p1: @@ -9374,6 +9393,8 @@ void Sema::DefineDefaultedComparison(SourceLocation UseLoc, FunctionDecl *FD, // Add a context note for diagnostics produced after this point. Scope.addContextNote(UseLoc); + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, FD); + { // Build and set up the function body. // The first parameter has type maybe-ref-to maybe-const T, use that to get @@ -14367,6 +14388,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, Constructor); assert((Constructor->isDefaulted() && Constructor->isDefaultConstructor() && !Constructor->doesThisDeclarationHaveABody() && !Constructor->isDeleted()) && @@ -14666,6 +14688,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, Destructor); assert((Destructor->isDefaulted() && !Destructor->doesThisDeclarationHaveABody() && !Destructor->isDeleted()) && @@ -15356,6 +15379,7 @@ static void diagnoseDeprecatedCopyOperation(Sema &S, CXXMethodDecl *CopyOp) { void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CXXMethodDecl *CopyAssignOperator) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, CopyAssignOperator); assert((CopyAssignOperator->isDefaulted() && CopyAssignOperator->isOverloadedOperator() && CopyAssignOperator->getOverloadedOperator() == OO_Equal && @@ -15743,6 +15767,7 @@ static void checkMoveAssignmentForRepeatedMove(Sema &S, CXXRecordDecl *Class, void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, CXXMethodDecl *MoveAssignOperator) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, MoveAssignOperator); assert((MoveAssignOperator->isDefaulted() && MoveAssignOperator->isOverloadedOperator() && MoveAssignOperator->getOverloadedOperator() == OO_Equal && @@ -16076,6 +16101,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *CopyConstructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, CopyConstructor); assert((CopyConstructor->isDefaulted() && CopyConstructor->isCopyConstructor() && !CopyConstructor->doesThisDeclarationHaveABody() && @@ -16214,6 +16240,7 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *MoveConstructor) { + DefaultedFunctionFPFeaturesRAII RestoreFP(*this, MoveConstructor); assert((MoveConstructor->isDefaulted() && MoveConstructor->isMoveConstructor() && !MoveConstructor->doesThisDeclarationHaveABody() && @@ -18776,6 +18803,16 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) { return; } + // Only allocate DefaultedOrDeletedFunctionInfo if we actually have + // non-default FP features to stash. This avoids memory overhead for + // the vast majority of defaulted functions. + if (!FD->getDefaultedOrDeletedInfo() && + CurFPFeatureOverrides().requiresTrailingStorage()) { + FD->setDefaultedOrDeletedInfo( + FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( + Context, /*Lookups=*/{}, CurFPFeatureOverrides())); + } + if (DefKind.isComparison()) { if (CheckExplicitlyDefaultedComparison(nullptr, FD, DefKind.asComparison())) FD->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c56203f10ac3c..a787d537f02f8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5515,11 +5515,10 @@ bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New, Lookups.push_back(DeclAccessPair::make(D, DA.getAccess())); } - // It's unlikely that substitution will change any declarations. Don't - // store an unnecessary copy in that case. New->setDefaultedOrDeletedInfo( AnyChanged ? FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - SemaRef.Context, Lookups) + SemaRef.Context, Lookups, DFI->getFPFeatures(), + DFI->getDeletedMessage()) : DFI); } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index bd684b89e194f..f484bc7e0bf55 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1094,6 +1094,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { StringLiteral *DeletedMessage = HasMessage ? cast(Record.readExpr()) : nullptr; + FPOptionsOverride FPFeatures = + FPOptionsOverride::getFromOpaqueInt(Record.readInt()); + unsigned NumLookups = Record.readInt(); SmallVector Lookups; for (unsigned I = 0; I != NumLookups; ++I) { @@ -1104,7 +1107,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setDefaultedOrDeletedInfo( FunctionDecl::DefaultedOrDeletedFunctionInfo::Create( - Reader.getContext(), Lookups, DeletedMessage)); + Reader.getContext(), Lookups, FPFeatures, DeletedMessage)); } } diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index f271769d8edf6..e3b81650d65a1 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -898,6 +898,8 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { if (DeletedMessage) Record.AddStmt(DeletedMessage); + Record.push_back(FDI->getFPFeatures().getAsOpaqueInt()); + Record.push_back(FDI->getUnqualifiedLookups().size()); for (DeclAccessPair P : FDI->getUnqualifiedLookups()) { Record.AddDeclRef(P.getDecl()); diff --git a/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp b/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp new file mode 100644 index 0000000000000..809c1fc864618 --- /dev/null +++ b/clang/test/CodeGenCXX/defaulted-function-fp-features.cpp @@ -0,0 +1,101 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++20 -emit-llvm -o - %s | FileCheck %s + +// CHECK-DAG: define {{.*}} @_ZeqRK6TargetS1_({{.*}}) [[NORMAL_ATTRS:#[0-9]+]] +// CHECK-DAG: define {{.*}} @_ZeqRK12StrictTargetS1_({{.*}}) [[STRICT_ATTRS:#[0-9]+]] +// CHECK-DAG: define {{.*}} @_ZN12AssignTargetaSERKS_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZN18StrictAssignTargetaSERKS_({{.*}}) [[STRICT_ATTRS]] + +// Templates +// CHECK-DAG: define {{.*}} @_ZeqRK14TemplateTargetIdES2_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZeqRK14TemplateTargetIfES2_({{.*}}) [[NORMAL_ATTRS]] +// CHECK-DAG: define {{.*}} @_ZeqRK20StrictTemplateTargetIdES2_({{.*}}) [[STRICT_ATTRS]] + +// --- NON-STRICT DECLARATIONS (at top of file, default FP is non-strict) --- + +struct Target { + double d; + friend bool operator==(const Target&, const Target&) = default; +}; + +struct Member { + double d; + Member& operator=(const Member& Other) { + d = Other.d + 1.0; + return *this; + } +}; + +struct AssignTarget { + Member m; +}; + +template +struct TemplateTarget { + T d; + friend bool operator==(const TemplateTarget&, const TemplateTarget&) = default; +}; + +// Trigger instantiation of TemplateTarget::operator== in non-strict context. +bool test_template_non_strict(TemplateTarget a, TemplateTarget b) { + return a == b; +} + + +// --- STRICT CONTEXT (pragmas enabled) --- +#pragma STDC FENV_ACCESS ON + +// Use-sites triggering synthesis of non-strict defaulted functions in strict context. + +bool test_non_strict_cmp(Target a, Target b) { + return a == b; +} + +void test_non_strict_assign(AssignTarget& a, AssignTarget& b) { + a = b; +} + +// Trigger instantiation of TemplateTarget::operator== in strict context. +// It should still be non-strict because the template was defined in non-strict context. +bool test_template_strict(TemplateTarget a, TemplateTarget b) { + return a == b; +} + +// Strict declarations (must get strictfp) + +struct StrictTarget { + double d; + friend bool operator==(const StrictTarget&, const StrictTarget&) = default; +}; + +bool test_strict_cmp(StrictTarget a, StrictTarget b) { + return a == b; +} + +struct StrictAssignTarget { + Member m; +}; + +void test_strict_assign(StrictAssignTarget& a, StrictAssignTarget& b) { + a = b; +} + +template +struct StrictTemplateTarget { + T d; + friend bool operator==(const StrictTemplateTarget&, const StrictTemplateTarget&) = default; +}; + + +// --- NON-STRICT CONTEXT AGAIN --- +#pragma STDC FENV_ACCESS OFF + +// Trigger instantiation of StrictTemplateTarget::operator== in non-strict context. +// It should be strict because the template was defined in strict context. +bool test_strict_template_non_strict(StrictTemplateTarget a, StrictTemplateTarget b) { + return a == b; +} + + +// CHECK-DAG: attributes [[STRICT_ATTRS]] = { {{.*}}strictfp{{.*}} } +// CHECK-DAG: attributes [[NORMAL_ATTRS]] = { {{.*}} } +// CHECK-NOT: attributes [[NORMAL_ATTRS]] = { {{.*}}strictfp From 64a9e0c2a5301797ca4cc89b9a332f01e34404fe Mon Sep 17 00:00:00 2001 From: David Green Date: Thu, 9 Jul 2026 20:02:54 +0100 Subject: [PATCH 005/125] [AArch64][GlobalISel] Update scalar types in selection tests. NFC (#208534) --- .../GlobalISel/select-arith-extended-reg.mir | 32 +-- .../GlobalISel/select-atomic-load-store.mir | 12 +- .../AArch64/GlobalISel/select-atomicrmw.mir | 88 ++++---- .../CodeGen/AArch64/GlobalISel/select-bit.mir | 60 ++--- .../GlobalISel/select-bitcast-bigendian.mir | 6 +- .../AArch64/GlobalISel/select-bitcast.mir | 54 ++--- .../CodeGen/AArch64/GlobalISel/select-br.mir | 2 +- .../GlobalISel/select-brcond-of-binop.mir | 8 +- .../AArch64/GlobalISel/select-bswap.mir | 38 ++-- .../GlobalISel/select-build-vector.mir | 92 ++++---- .../CodeGen/AArch64/GlobalISel/select-cbz.mir | 52 ++--- .../AArch64/GlobalISel/select-cmpxchg.mir | 20 +- .../GlobalISel/select-concat-vectors.mir | 32 +-- .../AArch64/GlobalISel/select-const-pool.mir | 8 +- .../GlobalISel/select-const-vector.mir | 58 ++--- .../AArch64/GlobalISel/select-constant.mir | 36 +-- .../CodeGen/AArch64/GlobalISel/select-ext.mir | 56 ++--- .../AArch64/GlobalISel/select-extload.mir | 14 +- .../select-extract-vector-elt-with-extend.mir | 158 +++++++------- .../GlobalISel/select-extract-vector-elt.mir | 116 +++++----- .../AArch64/GlobalISel/select-extract.mir | 10 +- .../GlobalISel/select-fp-index-load.mir | 96 ++++---- .../GlobalISel/select-frint-nofp16.mir | 2 +- .../GlobalISel/select-gv-cmodel-large.mir | 20 +- .../GlobalISel/select-gv-cmodel-tiny.mir | 14 +- .../AArch64/GlobalISel/select-hint.mir | 52 ++--- .../CodeGen/AArch64/GlobalISel/select-imm.mir | 8 +- .../GlobalISel/select-insert-extract.mir | 36 +-- .../GlobalISel/select-insert-vector-elt.mir | 128 +++++------ .../GlobalISel/select-int-ptr-casts.mir | 26 +-- .../select-intrinsic-aarch64-hint.mir | 2 +- .../select-intrinsic-crypto-aesmc.mir | 10 +- .../select-jump-table-brjt-constrain.mir | 10 +- .../CodeGen/AArch64/GlobalISel/select-ld2.mir | 64 +++--- .../CodeGen/AArch64/GlobalISel/select-ld4.mir | 96 ++++---- .../GlobalISel/select-ldaxr-intrin.mir | 16 +- .../AArch64/GlobalISel/select-ldxr-intrin.mir | 24 +- .../select-load-store-vector-of-ptr.mir | 12 +- .../AArch64/GlobalISel/select-load.mir | 206 +++++++++--------- .../AArch64/GlobalISel/select-modf.mir | 42 ++-- .../GlobalISel/select-neon-vcvtfxu2fp.mir | 6 +- .../AArch64/GlobalISel/select-ptr-add.mir | 38 ++-- .../AArch64/GlobalISel/select-reduce-add.mir | 20 +- .../select-redundant-zext-of-load.mir | 16 +- .../GlobalISel/select-redundant-zext.mir | 6 +- .../CodeGen/AArch64/GlobalISel/select-rev.mir | 80 +++---- .../AArch64/GlobalISel/select-sadde.mir | 96 ++++---- .../AArch64/GlobalISel/select-saddo.mir | 54 ++--- .../AArch64/GlobalISel/select-sbfx.mir | 40 ++-- .../GlobalISel/select-scalar-merge.mir | 8 +- .../AArch64/GlobalISel/select-sextload.mir | 8 +- .../GlobalISel/select-shuffle-vector.mir | 32 +-- .../select-shufflevec-undef-mask-elt.mir | 12 +- .../AArch64/GlobalISel/select-ssube.mir | 96 ++++---- .../AArch64/GlobalISel/select-ssubo.mir | 54 ++--- .../CodeGen/AArch64/GlobalISel/select-st2.mir | 72 +++--- .../AArch64/GlobalISel/select-static.mir | 44 ++-- .../GlobalISel/select-stlxr-intrin.mir | 16 +- .../select-store-truncating-float.mir | 18 +- .../AArch64/GlobalISel/select-store.mir | 198 ++++++++--------- .../CodeGen/AArch64/GlobalISel/select-stx.mir | 16 +- .../GlobalISel/select-tbnz-from-cmp.mir | 48 ++-- .../CodeGen/AArch64/GlobalISel/select-trn.mir | 112 +++++----- .../AArch64/GlobalISel/select-trunc.mir | 4 +- .../GlobalISel/select-truncstore-atomic.mir | 24 +- .../AArch64/GlobalISel/select-uadde.mir | 96 ++++---- .../AArch64/GlobalISel/select-uaddo.mir | 54 ++--- .../AArch64/GlobalISel/select-ubfx.mir | 40 ++-- .../AArch64/GlobalISel/select-unmerge.mir | 116 +++++----- .../AArch64/GlobalISel/select-usube.mir | 96 ++++---- .../AArch64/GlobalISel/select-usubo.mir | 52 ++--- .../CodeGen/AArch64/GlobalISel/select-uzp.mir | 16 +- .../AArch64/GlobalISel/select-vector-icmp.mir | 72 +++--- .../GlobalISel/select-vector-shift.mir | 24 +- .../select-with-no-legality-check.mir | 14 +- .../GlobalISel/select-zext-as-copy.mir | 4 +- .../AArch64/GlobalISel/select-zextload.mir | 60 ++--- .../CodeGen/AArch64/GlobalISel/select-zip.mir | 48 ++-- 78 files changed, 1813 insertions(+), 1813 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir index 9389fff12fb93..49ed1f35b03af 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-arith-extended-reg.mir @@ -203,8 +203,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_SEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_SEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -229,8 +229,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ZEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ZEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -255,8 +255,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ANYEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ANYEXT %1(i8) %add_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_ADD %add_lhs, %ext $w3 = COPY %res(i32) @@ -541,8 +541,8 @@ body: | bb.0: liveins: $w1, $w2, $x2 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_SEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_SEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -567,8 +567,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ZEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ZEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -593,8 +593,8 @@ body: | ; CHECK-NEXT: $w3 = COPY %res ; CHECK-NEXT: RET_ReallyLR implicit $w3 %wide_1:gpr(i32) = COPY $w1 - %1:gpr(s8) = G_TRUNC %wide_1 - %ext:gpr(i32) = G_ANYEXT %1(s8) + %1:gpr(i8) = G_TRUNC %wide_1 + %ext:gpr(i32) = G_ANYEXT %1(i8) %sub_lhs:gpr(i32) = COPY $w2 %res:gpr(i32) = G_SUB %sub_lhs, %ext $w3 = COPY %res(i32) @@ -721,8 +721,8 @@ body: | %0:gpr(p0) = COPY $x0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 - %small:gpr(s8) = G_TRUNC %1 - %zext:gpr(i64) = G_ZEXT %small(s8) + %small:gpr(i8) = G_TRUNC %1 + %zext:gpr(i64) = G_ZEXT %small(i8) %cst:gpr(i64) = G_CONSTANT i64 3 %shl:gpr(i64) = G_SHL %zext, %cst(i64) %gep:gpr(p0) = G_PTR_ADD %0, %shl(i64) @@ -793,8 +793,8 @@ body: | %0:gpr(p0) = COPY $x0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 - %small:gpr(s8) = G_TRUNC %1 - %zext:gpr(i64) = G_SEXT %small(s8) + %small:gpr(i8) = G_TRUNC %1 + %zext:gpr(i64) = G_SEXT %small(i8) %cst:gpr(i64) = G_CONSTANT i64 3 %shl:gpr(i64) = G_SHL %zext, %cst(i64) %gep:gpr(p0) = G_PTR_ADD %0, %shl(i64) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir index da3c962f2468e..5d9b7e0d42a01 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomic-load-store.mir @@ -32,12 +32,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (s8) from %ir.ptr, align 8) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (i8) from %ir.ptr, align 8) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(s32) = G_LOAD %0(p0) :: (load acquire (s8) from %ir.ptr, align 8) - $w0 = COPY %2(s32) + %2:gpr(i32) = G_LOAD %0(p0) :: (load acquire (i8) from %ir.ptr, align 8) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -50,13 +50,13 @@ body: | bb.1: ; CHECK-LABEL: name: anyext_load_monotonic_i32 ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY $xzr - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load monotonic (s32) from `ptr null`) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load monotonic (i32) from `ptr null`) ; CHECK-NEXT: %ld:gpr64all = SUBREG_TO_REG [[LDRWui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY %ld ; CHECK-NEXT: RET_ReallyLR implicit $x0 %1:gpr(p0) = G_CONSTANT i64 0 - %ld:gpr(s64) = G_LOAD %1(p0) :: (load monotonic (s32) from `ptr null`) - $x0 = COPY %ld(s64) + %ld:gpr(i64) = G_LOAD %1(p0) :: (load monotonic (i32) from `ptr null`) + $x0 = COPY %ld(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir index 457c5d6411b64..7d8c1e0f1b28e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-atomicrmw.mir @@ -33,12 +33,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[SWPX:%[0-9]+]]:gpr64 = SWPX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[SWPX:%[0-9]+]]:gpr64 = SWPX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[SWPX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s64) = G_ATOMICRMW_XCHG %0, %1 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i64) = G_ATOMICRMW_XCHG %0, %1 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %2(i64) ... --- name: atomicrmw_add_i64 @@ -55,12 +55,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[LDADDX:%[0-9]+]]:gpr64 = LDADDX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[LDADDX:%[0-9]+]]:gpr64 = LDADDX [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDADDX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s64) = G_ATOMICRMW_ADD %0, %1 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i64) = G_ATOMICRMW_ADD %0, %1 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %2(i64) ... --- name: atomicrmw_add_i32 @@ -76,12 +76,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (s32) on %ir.addr) + ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDADDALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -98,12 +98,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (s32) on %ir.addr) + ; CHECK-NEXT: [[LDADDALW:%[0-9]+]]:gpr32 = LDADDALW [[MOVi32imm]], [[COPY]] :: (load store seq_cst (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDADDALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_ADD %0, %1 :: (load store seq_cst (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -121,12 +121,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[ORNWrr:%[0-9]+]]:gpr32 = ORNWrr $wzr, [[MOVi32imm]] - ; CHECK-NEXT: [[LDCLRAW:%[0-9]+]]:gpr32 = LDCLRAW [[ORNWrr]], [[COPY]] :: (load store acquire (s32) on %ir.addr) + ; CHECK-NEXT: [[LDCLRAW:%[0-9]+]]:gpr32 = LDCLRAW [[ORNWrr]], [[COPY]] :: (load store acquire (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDCLRAW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_AND %0, %1 :: (load store acquire (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_AND %0, %1 :: (load store acquire (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -143,12 +143,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSETLW:%[0-9]+]]:gpr32 = LDSETLW [[MOVi32imm]], [[COPY]] :: (load store release (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSETLW:%[0-9]+]]:gpr32 = LDSETLW [[MOVi32imm]], [[COPY]] :: (load store release (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSETLW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_OR %0, %1 :: (load store release (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_OR %0, %1 :: (load store release (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -165,12 +165,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDEORALW:%[0-9]+]]:gpr32 = LDEORALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDEORALW:%[0-9]+]]:gpr32 = LDEORALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDEORALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_XOR %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_XOR %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -187,12 +187,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSMINALW:%[0-9]+]]:gpr32 = LDSMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSMINALW:%[0-9]+]]:gpr32 = LDSMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSMINALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_MIN %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_MIN %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -209,12 +209,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDSMAXALW:%[0-9]+]]:gpr32 = LDSMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDSMAXALW:%[0-9]+]]:gpr32 = LDSMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDSMAXALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_MAX %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_MAX %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -231,12 +231,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDUMINALW:%[0-9]+]]:gpr32 = LDUMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDUMINALW:%[0-9]+]]:gpr32 = LDUMINALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDUMINALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_UMIN %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_UMIN %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... --- @@ -253,10 +253,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[LDUMAXALW:%[0-9]+]]:gpr32 = LDUMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (s32) on %ir.addr) + ; CHECK-NEXT: [[LDUMAXALW:%[0-9]+]]:gpr32 = LDUMAXALW [[MOVi32imm]], [[COPY]] :: (load store acq_rel (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDUMAXALW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s32) = G_ATOMICRMW_UMAX %0, %1 :: (load store acq_rel (s32) on %ir.addr) - $w0 = COPY %2(s32) + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i32) = G_ATOMICRMW_UMAX %0, %1 :: (load store acq_rel (i32) on %ir.addr) + $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir index e3edb62809774..e64da1ec822ce 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bit.mir @@ -20,11 +20,11 @@ body: | ; CHECK-NEXT: %bit:fpr64 = BSPv8i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $d0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %lhs:fpr(<2 x s32>) = COPY $d0 - %mhs:fpr(<2 x s32>) = COPY $d1 - %rhs:fpr(<2 x s32>) = COPY $d2 - %bit:fpr(<2 x s32>) = G_BSP %lhs, %mhs, %rhs - $d0 = COPY %bit(<2 x s32>) + %lhs:fpr(<2 x i32>) = COPY $d0 + %mhs:fpr(<2 x i32>) = COPY $d1 + %rhs:fpr(<2 x i32>) = COPY $d2 + %bit:fpr(<2 x i32>) = G_BSP %lhs, %mhs, %rhs + $d0 = COPY %bit(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -45,11 +45,11 @@ body: | ; CHECK-NEXT: %bit:fpr64 = BSPv8i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $d0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %lhs:fpr(<4 x s16>) = COPY $d0 - %mhs:fpr(<4 x s16>) = COPY $d1 - %rhs:fpr(<4 x s16>) = COPY $d2 - %bit:fpr(<4 x s16>) = G_BSP %lhs, %mhs, %rhs - $d0 = COPY %bit(<4 x s16>) + %lhs:fpr(<4 x i16>) = COPY $d0 + %mhs:fpr(<4 x i16>) = COPY $d1 + %rhs:fpr(<4 x i16>) = COPY $d2 + %bit:fpr(<4 x i16>) = G_BSP %lhs, %mhs, %rhs + $d0 = COPY %bit(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -71,11 +71,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<2 x s64>) = COPY $q0 - %mhs:fpr(<2 x s64>) = COPY $q1 - %rhs:fpr(<2 x s64>) = COPY $q2 - %bit:fpr(<2 x s64>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<2 x s64>) + %lhs:fpr(<2 x i64>) = COPY $q0 + %mhs:fpr(<2 x i64>) = COPY $q1 + %rhs:fpr(<2 x i64>) = COPY $q2 + %bit:fpr(<2 x i64>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -97,11 +97,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<4 x s32>) = COPY $q0 - %mhs:fpr(<4 x s32>) = COPY $q1 - %rhs:fpr(<4 x s32>) = COPY $q2 - %bit:fpr(<4 x s32>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<4 x s32>) + %lhs:fpr(<4 x i32>) = COPY $q0 + %mhs:fpr(<4 x i32>) = COPY $q1 + %rhs:fpr(<4 x i32>) = COPY $q2 + %bit:fpr(<4 x i32>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -123,11 +123,11 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<8 x s16>) = COPY $q0 - %mhs:fpr(<8 x s16>) = COPY $q1 - %rhs:fpr(<8 x s16>) = COPY $q2 - %bit:fpr(<8 x s16>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<8 x s16>) + %lhs:fpr(<8 x i16>) = COPY $q0 + %mhs:fpr(<8 x i16>) = COPY $q1 + %rhs:fpr(<8 x i16>) = COPY $q2 + %bit:fpr(<8 x i16>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -149,9 +149,9 @@ body: | ; CHECK-NEXT: %bit:fpr128 = BSPv16i8 %lhs, %mhs, %rhs ; CHECK-NEXT: $q0 = COPY %bit ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lhs:fpr(<16 x s8>) = COPY $q0 - %mhs:fpr(<16 x s8>) = COPY $q1 - %rhs:fpr(<16 x s8>) = COPY $q2 - %bit:fpr(<16 x s8>) = G_BSP %lhs, %mhs, %rhs - $q0 = COPY %bit(<16 x s8>) + %lhs:fpr(<16 x i8>) = COPY $q0 + %mhs:fpr(<16 x i8>) = COPY $q1 + %rhs:fpr(<16 x i8>) = COPY $q2 + %bit:fpr(<16 x i8>) = G_BSP %lhs, %mhs, %rhs + $q0 = COPY %bit(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir index 74436c21d79d8..fb38abd071c0f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast-bigendian.mir @@ -17,7 +17,7 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[COPY1]] ; CHECK-NEXT: [[REV64v2i32_:%[0-9]+]]:fpr64 = REV64v2i32 [[COPY2]] ; CHECK-NEXT: $x0 = COPY [[REV64v2i32_]] - %0:fpr(<2 x s32>) = COPY $x0 - %1:fpr(s64) = G_BITCAST %0 - $x0 = COPY %1(s64) + %0:fpr(<2 x i32>) = COPY $x0 + %1:fpr(i64) = G_BITCAST %0 + $x0 = COPY %1(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir index e615b4d8efbb4..8ffea5447afde 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bitcast.mir @@ -35,9 +35,9 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[COPY1]] ; CHECK-NEXT: $w0 = COPY [[COPY2]] - %0(s32) = COPY $w0 - %1(<2 x s16>) = G_BITCAST %0 - %2(s32) = G_BITCAST %1 + %0(i32) = COPY $w0 + %1(<2 x i16>) = G_BITCAST %0 + %2(i32) = G_BITCAST %1 $w0 = COPY %2 ... @@ -61,9 +61,9 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY [[COPY1]] ; CHECK-NEXT: $s0 = COPY [[COPY2]] - %0(s32) = COPY $s0 - %1(<2 x s16>) = G_BITCAST %0 - %2(s32) = G_BITCAST %1 + %0(i32) = COPY $s0 + %1(<2 x i16>) = G_BITCAST %0 + %2(i32) = G_BITCAST %1 $s0 = COPY %2 ... @@ -86,8 +86,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY $w0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]] ; CHECK-NEXT: $s0 = COPY [[COPY1]] - %0(s32) = COPY $w0 - %1(<2 x s16>) = G_BITCAST %0 + %0(i32) = COPY $w0 + %1(<2 x i16>) = G_BITCAST %0 $s0 = COPY %1 ... @@ -110,9 +110,9 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[COPY]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %0(<2 x s16>) = COPY $s0 - %1(s32) = G_BITCAST %0 - $w0 = COPY %1(s32) + %0(<2 x i16>) = COPY $s0 + %1(i32) = G_BITCAST %0 + $w0 = COPY %1(i32) ... --- @@ -136,10 +136,10 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]] ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64 = COPY [[COPY1]] ; CHECK-NEXT: $x0 = COPY [[COPY2]] - %0(s64) = COPY $x0 - %1(<2 x s32>) = G_BITCAST %0 - %2(s64) = G_BITCAST %1 - $x0 = COPY %2(s64) + %0(i64) = COPY $x0 + %1(<2 x i32>) = G_BITCAST %0 + %2(i64) = G_BITCAST %1 + $x0 = COPY %2(i64) ... --- @@ -160,8 +160,8 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $d0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 $d0 = COPY %1 ... @@ -183,8 +183,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]] ; CHECK-NEXT: $d0 = COPY [[COPY1]] - %0(s64) = COPY $x0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $x0 + %1(<2 x i32>) = G_BITCAST %0 $d0 = COPY %1 ... @@ -207,8 +207,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64all = COPY [[COPY]] ; CHECK-NEXT: $x0 = COPY [[COPY1]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 $x0 = COPY %1 ... @@ -230,9 +230,9 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<2 x s32>) = G_BITCAST %0 - $x0 = COPY %1(<2 x s32>) + %0(i64) = COPY $d0 + %1(<2 x i32>) = G_BITCAST %0 + $x0 = COPY %1(<2 x i32>) ... --- @@ -253,7 +253,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $d0 - %1(<8 x s8>) = G_BITCAST %0 - $x0 = COPY %1(<8 x s8>) + %0(i64) = COPY $d0 + %1(<8 x i8>) = G_BITCAST %0 + $x0 = COPY %1(<8 x i8>) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir index e47411b7b178a..fae3870534ad9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-br.mir @@ -42,7 +42,7 @@ registers: body: | bb.0: successors: %bb.0, %bb.1 - %1(s32) = COPY $w0 + %1(i32) = COPY $w0 G_BRCOND %1, %bb.1 G_BR %bb.0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir index d0f2c9ceed7ef..5df0ea7811e83 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-brcond-of-binop.mir @@ -13,7 +13,7 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: TBZW [[LDRBBui]], 0, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: @@ -26,7 +26,7 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %8:gpr(i8) = G_LOAD %0(p0) :: (load (s8)) + %8:gpr(i8) = G_LOAD %0(p0) :: (load (i8)) %4:gpr(i32) = G_ANYEXT %8(i8) %5:gpr(i32) = G_CONSTANT i32 1 %6:gpr(i32) = G_XOR %4, %5 @@ -52,7 +52,7 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: TBZW [[LDRBBui]], 0, %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: @@ -67,7 +67,7 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %8:gpr(i8) = G_LOAD %0(p0) :: (load (s8)) + %8:gpr(i8) = G_LOAD %0(p0) :: (load (i8)) %4:gpr(i64) = G_ANYEXT %8(i8) %5:gpr(i64) = G_CONSTANT i64 1 %6:gpr(i64) = G_XOR %4, %5 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir index 5e0121682e327..46773eab46eaf 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-bswap.mir @@ -21,8 +21,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0 ; CHECK-NEXT: [[REVWr:%[0-9]+]]:gpr32 = REVWr [[COPY]] ; CHECK-NEXT: $w0 = COPY [[REVWr]] - %0(s32) = COPY $w0 - %1(s32) = G_BSWAP %0 + %0(i32) = COPY $w0 + %1(i32) = G_BSWAP %0 $w0 = COPY %1 ... @@ -45,8 +45,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: [[REVXr:%[0-9]+]]:gpr64 = REVXr [[COPY]] ; CHECK-NEXT: $x0 = COPY [[REVXr]] - %0(s64) = COPY $x0 - %1(s64) = G_BSWAP %0 + %0(i64) = COPY $x0 + %1(i64) = G_BSWAP %0 $x0 = COPY %1 ... @@ -68,9 +68,9 @@ body: | ; CHECK-NEXT: [[REV16v8i8_:%[0-9]+]]:fpr64 = REV16v8i8 [[COPY]] ; CHECK-NEXT: $d0 = COPY [[REV16v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = G_BSWAP %0 - $d0 = COPY %1(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = G_BSWAP %0 + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -91,9 +91,9 @@ body: | ; CHECK-NEXT: [[REV16v16i8_:%[0-9]+]]:fpr128 = REV16v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV16v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = G_BSWAP %0 - $q0 = COPY %1(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = G_BSWAP %0 + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -115,9 +115,9 @@ body: | ; CHECK-NEXT: [[REV32v16i8_:%[0-9]+]]:fpr128 = REV32v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV32v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = G_BSWAP %0 - $q0 = COPY %1(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = G_BSWAP %0 + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -139,9 +139,9 @@ body: | ; CHECK-NEXT: [[REV32v8i8_:%[0-9]+]]:fpr64 = REV32v8i8 [[COPY]] ; CHECK-NEXT: $d0 = COPY [[REV32v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = G_BSWAP %0 - $d0 = COPY %1(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = G_BSWAP %0 + $d0 = COPY %1(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -163,9 +163,9 @@ body: | ; CHECK-NEXT: [[REV64v16i8_:%[0-9]+]]:fpr128 = REV64v16i8 [[COPY]] ; CHECK-NEXT: $q0 = COPY [[REV64v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = G_BSWAP %0 - $q0 = COPY %1(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = G_BSWAP %0 + $q0 = COPY %1(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir index 0b2121db4e7c4..4e88d5edd6df2 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-build-vector.mir @@ -33,12 +33,12 @@ body: | ; CHECK-NEXT: [[INSvi32lane2:%[0-9]+]]:fpr128 = INSvi32lane [[INSvi32lane1]], 3, [[INSERT_SUBREG3]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s32) = COPY $s0 - %1:fpr(s32) = COPY $s1 - %2:fpr(s32) = COPY $s2 - %3:fpr(s32) = COPY $s3 - %4:fpr(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32) - $q0 = COPY %4(<4 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(i32) = COPY $s1 + %2:fpr(i32) = COPY $s2 + %3:fpr(i32) = COPY $s3 + %4:fpr(<4 x i32>) = G_BUILD_VECTOR %0(i32), %1(i32), %2(i32), %3(i32) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -67,10 +67,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s64) = COPY $d0 - %1:fpr(s64) = COPY $d1 - %4:fpr(<2 x s64>) = G_BUILD_VECTOR %0(s64), %1(s64) - $q0 = COPY %4(<2 x s64>) + %0:fpr(i64) = COPY $d0 + %1:fpr(i64) = COPY $d1 + %4:fpr(<2 x i64>) = G_BUILD_VECTOR %0(i64), %1(i64) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -101,12 +101,12 @@ body: | ; CHECK-NEXT: [[INSvi32gpr2:%[0-9]+]]:fpr128 = INSvi32gpr [[INSvi32gpr1]], 3, [[COPY3]] ; CHECK-NEXT: $q0 = COPY [[INSvi32gpr2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = COPY $w2 - %3:gpr(s32) = COPY $w3 - %4:fpr(<4 x s32>) = G_BUILD_VECTOR %0(s32), %1(s32), %2(s32), %3(s32) - $q0 = COPY %4(<4 x s32>) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = COPY $w2 + %3:gpr(i32) = COPY $w3 + %4:fpr(<4 x i32>) = G_BUILD_VECTOR %0(i32), %1(i32), %2(i32), %3(i32) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -133,10 +133,10 @@ body: | ; CHECK-NEXT: [[INSvi64gpr:%[0-9]+]]:fpr128 = INSvi64gpr [[INSERT_SUBREG]], 1, [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[INSvi64gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %4:fpr(<2 x s64>) = G_BUILD_VECTOR %0(s64), %1(s64) - $q0 = COPY %4(<2 x s64>) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %4:fpr(<2 x i64>) = G_BUILD_VECTOR %0(i64), %1(i64) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -191,13 +191,13 @@ body: | ; CHECK-NEXT: $q0 = COPY [[MOVIv2d_ns]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:gpr(s32) = G_CONSTANT i32 0 - %3:fpr(s32) = COPY %2(s32) - %4:fpr(s32) = COPY %2(s32) - %5:fpr(s32) = COPY %2(s32) - %6:fpr(s32) = COPY %2(s32) - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %3(s32), %4(s32), %5(s32), %6(s32) - $q0 = COPY %1(<4 x s32>) + %2:gpr(i32) = G_CONSTANT i32 0 + %3:fpr(i32) = COPY %2(i32) + %4:fpr(i32) = COPY %2(i32) + %5:fpr(i32) = COPY %2(i32) + %6:fpr(i32) = COPY %2(i32) + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %3(i32), %4(i32), %5(i32), %6(i32) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR ... --- @@ -222,17 +222,17 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:gpr(s8) = G_CONSTANT i8 0 - %3:fpr(s8) = COPY %2(s8) - %4:fpr(s8) = COPY %2(s8) - %5:fpr(s8) = COPY %2(s8) - %6:fpr(s8) = COPY %2(s8) - %7:fpr(s8) = COPY %2(s8) - %8:fpr(s8) = COPY %2(s8) - %9:fpr(s8) = COPY %2(s8) - %10:fpr(s8) = COPY %2(s8) - %1:fpr(<8 x s8>) = G_BUILD_VECTOR %3(s8), %4(s8), %5(s8), %6(s8), %7(s8), %8(s8), %9(s8), %10(s8) - $d0 = COPY %1(<8 x s8>) + %2:gpr(i8) = G_CONSTANT i8 0 + %3:fpr(i8) = COPY %2(i8) + %4:fpr(i8) = COPY %2(i8) + %5:fpr(i8) = COPY %2(i8) + %6:fpr(i8) = COPY %2(i8) + %7:fpr(i8) = COPY %2(i8) + %8:fpr(i8) = COPY %2(i8) + %9:fpr(i8) = COPY %2(i8) + %10:fpr(i8) = COPY %2(i8) + %1:fpr(<8 x i8>) = G_BUILD_VECTOR %3(i8), %4(i8), %5(i8), %6(i8), %7(i8), %8(i8), %9(i8), %10(i8) + $d0 = COPY %1(<8 x i8>) RET_ReallyLR ... --- @@ -253,10 +253,10 @@ body: | ; CHECK-NEXT: %bv:fpr128 = SUBREG_TO_REG %val, %subreg.ssub ; CHECK-NEXT: $q0 = COPY %bv ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %val:fpr(s32) = COPY $s0 - %undef:fpr(s32) = G_IMPLICIT_DEF - %bv:fpr(<4 x s32>) = G_BUILD_VECTOR %val(s32), %undef(s32), %undef(s32), %undef(s32) - $q0 = COPY %bv(<4 x s32>) + %val:fpr(i32) = COPY $s0 + %undef:fpr(i32) = G_IMPLICIT_DEF + %bv:fpr(<4 x i32>) = G_BUILD_VECTOR %val(i32), %undef(i32), %undef(i32), %undef(i32) + $q0 = COPY %bv(<4 x i32>) RET_ReallyLR implicit $q0 ... ... @@ -279,9 +279,9 @@ body: | ; CHECK-NEXT: %bv:fpr128 = INSERT_SUBREG [[DEF]], %val, %subreg.ssub ; CHECK-NEXT: $q0 = COPY %bv ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %val:gpr(s32) = COPY $w0 - %undef:gpr(s32) = G_IMPLICIT_DEF - %bv:fpr(<4 x s32>) = G_BUILD_VECTOR %val(s32), %undef(s32), %undef(s32), %undef(s32) - $q0 = COPY %bv(<4 x s32>) + %val:gpr(i32) = COPY $w0 + %undef:gpr(i32) = G_IMPLICIT_DEF + %bv:fpr(<4 x i32>) = G_BUILD_VECTOR %val(i32), %undef(i32), %undef(i32), %undef(i32) + $q0 = COPY %bv(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir index 0da29c9d0c110..7fd1c8b419ab9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-cbz.mir @@ -21,9 +21,9 @@ body: | liveins: $w0 successors: %bb.0, %bb.1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_ICMP intpred(eq), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -50,9 +50,9 @@ body: | liveins: $x0 successors: %bb.0, %bb.1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s32) = G_ICMP intpred(eq), %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i32) = G_ICMP intpred(eq), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -79,9 +79,9 @@ body: | liveins: $w0 successors: %bb.0, %bb.1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_ICMP intpred(ne), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -108,9 +108,9 @@ body: | liveins: $x0 successors: %bb.0, %bb.1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s32) = G_ICMP intpred(ne), %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i32) = G_ICMP intpred(ne), %0, %1 G_BRCOND %2, %bb.1 G_BR %bb.0 @@ -134,7 +134,7 @@ body: | ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64)) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -143,14 +143,14 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:gpr(p0) = G_INTTOPTR %2(s64) - %4:gpr(s32) = G_ICMP intpred(eq), %0(p0), %1 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:gpr(p0) = G_INTTOPTR %2(i64) + %4:gpr(i32) = G_ICMP intpred(eq), %0(p0), %1 G_BRCOND %4, %bb.3 bb.2: - %5:gpr(s64) = G_CONSTANT i64 0 - G_STORE %5(s64), %0(p0) :: (store (s64)) + %5:gpr(i64) = G_CONSTANT i64 0 + G_STORE %5(i64), %0(p0) :: (store (i64)) bb.3: RET_ReallyLR @@ -169,14 +169,14 @@ body: | ; CHECK-NEXT: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load (s64)) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64common = LDRXui [[COPY]], 0 :: (load (i64)) ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[LDRXui]], 42, 0, implicit-def $nzcv ; CHECK-NEXT: Bcc 0, %bb.2, implicit $nzcv ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.1: ; CHECK-NEXT: successors: %bb.2(0x80000000) ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64)) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -185,15 +185,15 @@ body: | liveins: $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(s64) = G_CONSTANT i64 42 - %4:gpr(s64) = G_CONSTANT i64 0 - %1:gpr(s64) = G_LOAD %0(p0) :: (load (s64)) - %5:gpr(s32) = G_ICMP intpred(eq), %1(s64), %2 + %2:gpr(i64) = G_CONSTANT i64 42 + %4:gpr(i64) = G_CONSTANT i64 0 + %1:gpr(i64) = G_LOAD %0(p0) :: (load (i64)) + %5:gpr(i32) = G_ICMP intpred(eq), %1(i64), %2 G_BRCOND %5, %bb.3 bb.2: - %6:gpr(s64) = G_CONSTANT i64 0 - G_STORE %6(s64), %0(p0) :: (store (s64)) + %6:gpr(i64) = G_CONSTANT i64 0 + G_STORE %6(i64), %0(p0) :: (store (i64)) bb.3: RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir index 33cb75f7b8f46..c8e343ac67972 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-cmpxchg.mir @@ -23,13 +23,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 - ; CHECK-NEXT: [[CASW:%[0-9]+]]:gpr32 = CASW [[COPY1]], [[MOVi32imm]], [[COPY]] :: (load store monotonic (s32) on %ir.addr) + ; CHECK-NEXT: [[CASW:%[0-9]+]]:gpr32 = CASW [[COPY1]], [[MOVi32imm]], [[COPY]] :: (load store monotonic (i32) on %ir.addr) ; CHECK-NEXT: $w0 = COPY [[CASW]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s32) on %ir.addr) - $w0 = COPY %3(s32) + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (i32) on %ir.addr) + $w0 = COPY %3(i32) ... --- @@ -48,11 +48,11 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $xzr ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 - ; CHECK-NEXT: [[CASX:%[0-9]+]]:gpr64 = CASX [[COPY1]], [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (s64) on %ir.addr) + ; CHECK-NEXT: [[CASX:%[0-9]+]]:gpr64 = CASX [[COPY1]], [[SUBREG_TO_REG]], [[COPY]] :: (load store monotonic (i64) on %ir.addr) ; CHECK-NEXT: $x0 = COPY [[CASX]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:gpr(s64) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (s64) on %ir.addr) - $x0 = COPY %3(s64) + %1:gpr(i64) = G_CONSTANT i64 0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:gpr(i64) = G_ATOMIC_CMPXCHG %0, %1, %2 :: (load store monotonic (i64) on %ir.addr) + $x0 = COPY %3(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir index 53d8b82509481..23dc446156173 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-concat-vectors.mir @@ -28,10 +28,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<4 x s32>) = G_CONCAT_VECTORS %0(<2 x s32>), %1(<2 x s32>) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<4 x i32>) = G_CONCAT_VECTORS %0(<2 x i32>), %1(<2 x i32>) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -62,10 +62,10 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<8 x s16>) = G_CONCAT_VECTORS %0(<4 x s16>), %1(<4 x s16>) - $q0 = COPY %2(<8 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<8 x i16>) = G_CONCAT_VECTORS %0(<4 x i16>), %1(<4 x i16>) + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -86,10 +86,10 @@ body: | ; CHECK-NEXT: %concat:fpr128 = INSERT_SUBREG [[DEF]], %a, %subreg.dsub ; CHECK-NEXT: $q0 = COPY %concat ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %a:fpr(<8 x s8>) = G_IMPLICIT_DEF - %b:fpr(<8 x s8>) = G_IMPLICIT_DEF - %concat:fpr(<16 x s8>) = G_CONCAT_VECTORS %a(<8 x s8>), %b(<8 x s8>) - $q0 = COPY %concat(<16 x s8>) + %a:fpr(<8 x i8>) = G_IMPLICIT_DEF + %b:fpr(<8 x i8>) = G_IMPLICIT_DEF + %concat:fpr(<16 x i8>) = G_CONCAT_VECTORS %a(<8 x i8>), %b(<8 x i8>) + $q0 = COPY %concat(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -113,10 +113,10 @@ body: | ; CHECK-NEXT: %concat:fpr128 = INSvi64lane [[INSERT_SUBREG1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY %concat ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %a:fpr(<8 x s8>) = COPY $d0 - %b:fpr(<8 x s8>) = COPY $d1 - %concat:fpr(<16 x s8>) = G_CONCAT_VECTORS %a(<8 x s8>), %b(<8 x s8>) - $q0 = COPY %concat(<16 x s8>) + %a:fpr(<8 x i8>) = COPY $d0 + %b:fpr(<8 x i8>) = COPY $d1 + %concat:fpr(<16 x i8>) = G_CONCAT_VECTORS %a(<8 x i8>), %b(<8 x i8>) + $q0 = COPY %concat(<16 x i8>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir index 041b76c54a5f8..25183359f4416 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-pool.mir @@ -22,10 +22,10 @@ body: | ; CHECK: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) ; CHECK: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s64) = G_FCONSTANT double 5.000000e-01 - %2:fpr(s64) = G_FCONSTANT double 1.600000e+01 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:fpr(f64) = G_FCONSTANT double 5.000000e-01 + %2:fpr(f64) = G_FCONSTANT double 1.600000e+01 + %1:fpr(<2 x f64>) = G_BUILD_VECTOR %2(f64), %3(f64) + G_STORE %1(<2 x f64>), %0(p0) :: (store (<2 x s64>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir index 34ac115640814..68b9aabe5431c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-const-vector.mir @@ -24,10 +24,10 @@ body: | ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s64) = G_FCONSTANT double 5.000000e-01 - %2:fpr(s64) = G_FCONSTANT double 1.600000e+01 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:fpr(f64) = G_FCONSTANT double 5.000000e-01 + %2:fpr(f64) = G_FCONSTANT double 1.600000e+01 + %1:fpr(<2 x f64>) = G_BUILD_VECTOR %2(f64), %3(f64) + G_STORE %1(<2 x f64>), %0(p0) :: (store (<2 x s64>)) RET_ReallyLR ... @@ -54,10 +54,10 @@ body: | ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:fpr(s32) = G_FCONSTANT float 5.000000e-01 - %2:fpr(s32) = G_FCONSTANT float 1.600000e+01 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %3(s32), %3(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %3:fpr(f32) = G_FCONSTANT float 5.000000e-01 + %2:fpr(f32) = G_FCONSTANT float 1.600000e+01 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %3(f32), %3(f32), %3(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... @@ -81,13 +81,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool) - ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x s64>)) + ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s64) = G_CONSTANT i64 67839 - %2:gpr(s64) = G_CONSTANT i64 12375 - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - G_STORE %1(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %3:gpr(i64) = G_CONSTANT i64 67839 + %2:gpr(i64) = G_CONSTANT i64 12375 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %3(i64) + G_STORE %1(<2 x i64>), %0(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -111,13 +111,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool) - ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x s32>)) + ; CHECK-NEXT: STRQui [[LDRQui]], [[COPY]], 0 :: (store (<4 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = G_CONSTANT i32 67839 - %2:gpr(s32) = G_CONSTANT i32 12375 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %2(s32), %3(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %3:gpr(i32) = G_CONSTANT i32 67839 + %2:gpr(i32) = G_CONSTANT i32 12375 + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32), %2(i32), %3(i32) + G_STORE %1(<4 x i32>), %0(p0) :: (store (<4 x i32>)) RET_ReallyLR ... @@ -142,13 +142,13 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool) - ; CHECK-NEXT: STRDui [[LDRDui]], [[COPY]], 0 :: (store (<2 x s32>)) + ; CHECK-NEXT: STRDui [[LDRDui]], [[COPY]], 0 :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = G_CONSTANT i32 67839 - %2:gpr(s32) = G_CONSTANT i32 12375 - %1:fpr(<2 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32) - G_STORE %1(<2 x s32>), %0(p0) :: (store (<2 x s32>)) + %3:gpr(i32) = G_CONSTANT i32 67839 + %2:gpr(i32) = G_CONSTANT i32 12375 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32) + G_STORE %1(<2 x i32>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -174,9 +174,9 @@ body: | ; CHECK-NEXT: STRQui [[MOVIv2d_ns]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_FCONSTANT float 0.000000e+00 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %2:fpr(f32) = G_FCONSTANT float 0.000000e+00 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %2(f32), %2(f32), %2(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... @@ -202,9 +202,9 @@ body: | ; CHECK-NEXT: STRQui [[MOVIv2d_ns]], [[COPY]], 0 :: (store (<4 x s32>)) ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_FCONSTANT float 0xFFFFFFFFE0000000 - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) - G_STORE %1(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %2:fpr(f32) = G_FCONSTANT float 0xFFFFFFFFE0000000 + %1:fpr(<4 x f32>) = G_BUILD_VECTOR %2(f32), %2(f32), %2(f32), %2(f32) + G_STORE %1(<4 x f32>), %0(p0) :: (store (<4 x s32>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir index de1775ef8369a..95f860bafb2b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir @@ -31,9 +31,9 @@ body: | ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]] ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0:gpr(s8) = G_CONSTANT i8 42 - %1:gpr(s32) = G_ANYEXT %0(s8) - $w0 = COPY %1(s32) + %0:gpr(i8) = G_CONSTANT i8 42 + %1:gpr(i32) = G_ANYEXT %0(i8) + $w0 = COPY %1(i32) ... --- @@ -46,9 +46,9 @@ body: | ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32all = COPY [[MOVi32imm]] ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0:gpr(s16) = G_CONSTANT i16 42 - %1:gpr(s32) = G_ANYEXT %0(s16) - $w0 = COPY %1(s32) + %0:gpr(i16) = G_CONSTANT i16 42 + %1:gpr(i32) = G_ANYEXT %0(i16) + $w0 = COPY %1(i32) ... --- @@ -63,8 +63,8 @@ body: | ; CHECK-LABEL: name: const_s32 ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 42 ; CHECK-NEXT: $w0 = COPY [[MOVi32imm]] - %0(s32) = G_CONSTANT i32 42 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 42 + $w0 = COPY %0(i32) ... --- @@ -79,8 +79,8 @@ body: | ; CHECK-LABEL: name: const_s64 ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 1234567890123 ; CHECK-NEXT: $x0 = COPY [[MOVi64imm]] - %0(s64) = G_CONSTANT i64 1234567890123 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 1234567890123 + $x0 = COPY %0(i64) ... --- @@ -95,8 +95,8 @@ body: | ; CHECK-LABEL: name: const_s32_zero ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $wzr ; CHECK-NEXT: $w0 = COPY [[COPY]] - %0(s32) = G_CONSTANT i32 0 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 0 + $w0 = COPY %0(i32) ... --- @@ -111,8 +111,8 @@ body: | ; CHECK-LABEL: name: const_s64_zero ; CHECK: [[COPY:%[0-9]+]]:gpr64 = COPY $xzr ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = G_CONSTANT i64 0 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 0 + $x0 = COPY %0(i64) ... --- @@ -201,8 +201,8 @@ body: | ; CHECK: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 42 ; CHECK-NEXT: $x0 = COPY [[MOVi64imm]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s64) = G_CONSTANT i64 42 - $x0 = COPY %0(s64) + %0:gpr(i64) = G_CONSTANT i64 42 + $x0 = COPY %0(i64) RET_ReallyLR implicit $x0 ... --- @@ -216,7 +216,7 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s64) = G_CONSTANT i64 42 - $x0 = COPY %0(s64) + %0:gpr(i64) = G_CONSTANT i64 42 + $x0 = COPY %0(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir index 4d76bdf405b3d..f041634351e24 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ext.mir @@ -21,10 +21,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 3 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<8 x s8>) = COPY $d0 - %v2:fpr(<8 x s8>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 3 - %shuf:fpr(<8 x s8>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<8 x i8>) = COPY $d0 + %v2:fpr(<8 x i8>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 3 + %shuf:fpr(<8 x i8>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -45,10 +45,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 3 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<16 x s8>) = COPY $q0 - %v2:fpr(<16 x s8>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 3 - %shuf:fpr(<16 x s8>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<16 x i8>) = COPY $q0 + %v2:fpr(<16 x i8>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 3 + %shuf:fpr(<16 x i8>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... @@ -69,10 +69,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 6 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<4 x s16>) = COPY $d0 - %v2:fpr(<4 x s16>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 6 - %shuf:fpr(<4 x s16>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<4 x i16>) = COPY $d0 + %v2:fpr(<4 x i16>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 6 + %shuf:fpr(<4 x i16>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -93,10 +93,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v2, %v1, 10 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<8 x s16>) = COPY $q0 - %v2:fpr(<8 x s16>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 10 - %shuf:fpr(<8 x s16>) = G_EXT %v2, %v1, %3(s32) + %v1:fpr(<8 x i16>) = COPY $q0 + %v2:fpr(<8 x i16>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 10 + %shuf:fpr(<8 x i16>) = G_EXT %v2, %v1, %3(i32) $q0 = COPY %shuf ... @@ -118,10 +118,10 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 12 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<4 x s32>) = COPY $q0 - %v2:fpr(<4 x s32>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 12 - %shuf:fpr(<4 x s32>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<4 x i32>) = COPY $q0 + %v2:fpr(<4 x i32>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 12 + %shuf:fpr(<4 x i32>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... @@ -142,10 +142,10 @@ body: | ; CHECK-NEXT: %v2:fpr64 = COPY $d1 ; CHECK-NEXT: %shuf:fpr64 = EXTv8i8 %v1, %v2, 2 ; CHECK-NEXT: $d0 = COPY %shuf - %v1:fpr(<2 x s32>) = COPY $d0 - %v2:fpr(<2 x s32>) = COPY $d1 - %3:gpr(s32) = G_CONSTANT i32 2 - %shuf:fpr(<2 x s32>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<2 x i32>) = COPY $d0 + %v2:fpr(<2 x i32>) = COPY $d1 + %3:gpr(i32) = G_CONSTANT i32 2 + %shuf:fpr(<2 x i32>) = G_EXT %v1, %v2, %3(i32) $d0 = COPY %shuf ... @@ -166,9 +166,9 @@ body: | ; CHECK-NEXT: %v2:fpr128 = COPY $q1 ; CHECK-NEXT: %shuf:fpr128 = EXTv16i8 %v1, %v2, 2 ; CHECK-NEXT: $q0 = COPY %shuf - %v1:fpr(<2 x s64>) = COPY $q0 - %v2:fpr(<2 x s64>) = COPY $q1 - %3:gpr(s32) = G_CONSTANT i32 2 - %shuf:fpr(<2 x s64>) = G_EXT %v1, %v2, %3(s32) + %v1:fpr(<2 x i64>) = COPY $q0 + %v2:fpr(<2 x i64>) = COPY $q1 + %3:gpr(i32) = G_CONSTANT i32 2 + %shuf:fpr(<2 x i64>) = G_EXT %v1, %v2, %3(i32) $q0 = COPY %shuf ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir index 5ba0353e23f76..9b14cedb66263 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extload.mir @@ -22,11 +22,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s16) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i16) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -42,11 +42,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1:gpr(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir index 69f97f449b430..58b51556c26b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt-with-extend.mir @@ -17,12 +17,12 @@ body: | ; CHECK-NEXT: [[SMOVvi32to64_:%[0-9]+]]:gpr64 = SMOVvi32to64 [[COPY]], 1 ; CHECK-NEXT: $x0 = COPY [[SMOVvi32to64_]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<4 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_SEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<4 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_SEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -44,12 +44,12 @@ body: | ; CHECK-NEXT: [[SMOVvi32to64_:%[0-9]+]]:gpr64 = SMOVvi32to64 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $x0 = COPY [[SMOVvi32to64_]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_SEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_SEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -70,12 +70,12 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[UMOVvi32_]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<4 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_ZEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<4 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_ZEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -98,12 +98,12 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[UMOVvi32_]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - %5:gpr(s32) = COPY %2(s32) - %4:gpr(s64) = G_ZEXT %5(s32) - $x0 = COPY %4(s64) + %0:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + %5:gpr(i32) = COPY %2(i32) + %4:gpr(i64) = G_ZEXT %5(i32) + $x0 = COPY %4(i64) RET_ReallyLR implicit $x0 ... @@ -123,12 +123,12 @@ body: | ; CHECK-NEXT: [[SMOVvi16to32_:%[0-9]+]]:gpr32 = SMOVvi16to32 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi16to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s16>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_SEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<8 x i16>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_SEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -148,12 +148,12 @@ body: | ; CHECK-NEXT: [[UMOVvi16_:%[0-9]+]]:gpr32 = UMOVvi16 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s16>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_ZEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<8 x i16>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_ZEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -175,12 +175,12 @@ body: | ; CHECK-NEXT: [[SMOVvi16to32_:%[0-9]+]]:gpr32 = SMOVvi16to32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi16to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<4 x s16>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_SEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<4 x i16>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_SEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -202,12 +202,12 @@ body: | ; CHECK-NEXT: [[UMOVvi16_:%[0-9]+]]:gpr32 = UMOVvi16 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<4 x s16>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %4(s64) - %6:gpr(s16) = COPY %3(s16) - %5:gpr(s32) = G_ZEXT %6(s16) - $w0 = COPY %5(s32) + %0:fpr(<4 x i16>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %4(i64) + %6:gpr(i16) = COPY %3(i16) + %5:gpr(i32) = G_ZEXT %6(i16) + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... @@ -227,12 +227,12 @@ body: | ; CHECK-NEXT: [[SMOVvi8to32_:%[0-9]+]]:gpr32 = SMOVvi8to32 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi8to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_SEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_SEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... --- @@ -251,12 +251,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[COPY]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_ZEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_ZEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... @@ -278,12 +278,12 @@ body: | ; CHECK-NEXT: [[SMOVvi8to32_:%[0-9]+]]:gpr32 = SMOVvi8to32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[SMOVvi8to32_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_SEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_SEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... --- @@ -304,12 +304,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %4:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %4(s64) - %7:gpr(s8) = COPY %3(s8) - %6:gpr(s32) = G_ZEXT %7(s8) - $w0 = COPY %6(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %4:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %4(i64) + %7:gpr(i8) = COPY %3(i8) + %6:gpr(i32) = G_ZEXT %7(i8) + $w0 = COPY %6(i32) RET_ReallyLR implicit $w0 ... @@ -326,11 +326,11 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[COPY]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %5:fpr(<16 x s8>) = G_IMPLICIT_DEF - %12:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(s8) = G_EXTRACT_VECTOR_ELT %5(<16 x s8>), %12(s64) - %11:gpr(s8) = COPY %4(s8) - %8:gpr(s16) = G_ANYEXT %11(s8) - %ext:gpr(s32) = G_ANYEXT %8(s16) - $w0 = COPY %ext(s32) + %5:fpr(<16 x i8>) = G_IMPLICIT_DEF + %12:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(i8) = G_EXTRACT_VECTOR_ELT %5(<16 x i8>), %12(i64) + %11:gpr(i8) = COPY %4(i8) + %8:gpr(i16) = G_ANYEXT %11(i8) + %ext:gpr(i32) = G_ANYEXT %8(i16) + $w0 = COPY %ext(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir index 375506f300de0..0f716ae7ab6e8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract-vector-elt.mir @@ -25,11 +25,11 @@ body: | ; CHECK-NEXT: [[DUPi32_:%[0-9]+]]:fpr32 = DUPi32 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $s0 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<2 x s32>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - $s0 = COPY %1(s32) + %0:fpr(<2 x i32>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + $s0 = COPY %1(i32) RET_ReallyLR implicit $s0 ... @@ -49,11 +49,11 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<2 x s32>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 0 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s32) = G_EXTRACT_VECTOR_ELT %0(<2 x s32>), %3(s64) - $s0 = COPY %1(s32) + %0:fpr(<2 x i32>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 0 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i32) = G_EXTRACT_VECTOR_ELT %0(<2 x i32>), %3(i64) + $s0 = COPY %1(i32) RET_ReallyLR implicit $s0 ... @@ -79,11 +79,11 @@ body: | ; CHECK-NEXT: [[DUPi64_:%[0-9]+]]:fpr64 = DUPi64 [[COPY]], 2 ; CHECK-NEXT: $d0 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 2 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s64) = G_EXTRACT_VECTOR_ELT %0(<2 x s64>), %3(s64) - $d0 = COPY %1(s64) + %0:fpr(<2 x i64>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 2 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i64) = G_EXTRACT_VECTOR_ELT %0(<2 x i64>), %3(i64) + $d0 = COPY %1(i64) RET_ReallyLR implicit $d0 ... @@ -111,11 +111,11 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[INSERT_SUBREG]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<4 x s16>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<4 x s16>), %3(s64) - $h0 = COPY %1(s16) + %0:fpr(<4 x i16>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<4 x i16>), %3(i64) + $h0 = COPY %1(i16) RET_ReallyLR implicit $h0 ... @@ -135,11 +135,11 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 1 - %3:fpr(s64) = COPY %2(s64) - %1:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %1(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 1 + %3:fpr(i64) = COPY %2(i64) + %1:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %1(i16) RET_ReallyLR implicit $h0 ... @@ -159,12 +159,12 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s64) = G_ZEXT %1 - %3:fpr(s64) = COPY %2(s64) - %4:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %4(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i64) = G_ZEXT %1 + %3:fpr(i64) = COPY %2(i64) + %4:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %4(i16) RET_ReallyLR implicit $h0 ... @@ -184,12 +184,12 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s32) = G_CONSTANT i32 1 - %2:gpr(s64) = G_SEXT %1 - %3:fpr(s64) = COPY %2(s64) - %4:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %3(s64) - $h0 = COPY %4(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i32) = G_CONSTANT i32 1 + %2:gpr(i64) = G_SEXT %1 + %3:fpr(i64) = COPY %2(i64) + %4:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %3(i64) + $h0 = COPY %4(i16) RET_ReallyLR implicit $h0 ... @@ -209,13 +209,13 @@ body: | ; CHECK-NEXT: [[DUPi16_:%[0-9]+]]:fpr16 = DUPi16 [[COPY]], 1 ; CHECK-NEXT: $h0 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:gpr(s64) = G_CONSTANT i64 1 - %2:gpr(s32) = G_TRUNC %1 - %3:gpr(s64) = G_SEXT %2 - %4:fpr(s64) = COPY %3(s64) - %5:fpr(s16) = G_EXTRACT_VECTOR_ELT %0(<8 x s16>), %4(s64) - $h0 = COPY %5(s16) + %0:fpr(<8 x i16>) = COPY $q0 + %1:gpr(i64) = G_CONSTANT i64 1 + %2:gpr(i32) = G_TRUNC %1 + %3:gpr(i64) = G_SEXT %2 + %4:fpr(i64) = COPY %3(i64) + %5:fpr(i16) = G_EXTRACT_VECTOR_ELT %0(<8 x i16>), %4(i64) + $h0 = COPY %5(i16) RET_ReallyLR implicit $h0 ... --- @@ -237,12 +237,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[COPY]], 0 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<16 x s8>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<16 x s8>), %2(s64) - %4:gpr(s8) = COPY %1(s8) - %3:gpr(s32) = G_ANYEXT %4(s8) - $w0 = COPY %3(s32) + %0:fpr(<16 x i8>) = COPY $q0 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<16 x i8>), %2(i64) + %4:gpr(i8) = COPY %1(i8) + %3:gpr(i32) = G_ANYEXT %4(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -267,12 +267,12 @@ body: | ; CHECK-NEXT: [[UMOVvi8_:%[0-9]+]]:gpr32 = UMOVvi8 [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $w0 = COPY [[UMOVvi8_]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:fpr(<8 x s8>) = COPY $d0 - %2:gpr(s64) = G_CONSTANT i64 0 - %1:fpr(s8) = G_EXTRACT_VECTOR_ELT %0(<8 x s8>), %2(s64) - %4:gpr(s8) = COPY %1(s8) - %3:gpr(s32) = G_ANYEXT %4(s8) - $w0 = COPY %3(s32) + %0:fpr(<8 x i8>) = COPY $d0 + %2:gpr(i64) = G_CONSTANT i64 0 + %1:fpr(i8) = G_EXTRACT_VECTOR_ELT %0(<8 x i8>), %2(i64) + %4:gpr(i8) = COPY %1(i8) + %3:gpr(i32) = G_ANYEXT %4(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -294,8 +294,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x p0>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 1 - %1:fpr(p0) = G_EXTRACT_VECTOR_ELT %0(<2 x p0>), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 1 + %1:fpr(p0) = G_EXTRACT_VECTOR_ELT %0(<2 x p0>), %2(i64) $d0 = COPY %1(p0) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir index d3795e36bd049..d7f67dc06aab3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-extract.mir @@ -19,11 +19,11 @@ body: | ; CHECK-NEXT: $d3 = COPY [[COPY1]] ; CHECK-NEXT: $d4 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d3 - %0:fpr(s128) = COPY $q0 - %2:fpr(s64) = G_EXTRACT %0(s128), 0 - %3:fpr(s64) = G_EXTRACT %0(s128), 64 - $d3 = COPY %2(s64) - $d4 = COPY %3(s64) + %0:fpr(i128) = COPY $q0 + %2:fpr(i64) = G_EXTRACT %0(i128), 0 + %3:fpr(i64) = G_EXTRACT %0(i128), 64 + $d3 = COPY %2(i64) + $d4 = COPY %3(i64) RET_ReallyLR implicit $d3 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir index b485cd2e88edd..0af08af070701 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp-index-load.mir @@ -16,15 +16,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr16 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $h0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $h0 = COPY %2(s16) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $h0 = COPY %2(i16) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -43,15 +43,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -70,15 +70,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpost [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s8)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i8)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -97,15 +97,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s16)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i16)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -124,15 +124,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpost [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s16)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i16)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -151,15 +151,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpost [[COPY]], 4 :: (load (s32)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpost [[COPY]], 4 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.ssub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (s32)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 0 :: (load (i32)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -178,15 +178,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr16 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $h0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $h0 = COPY %2(s16) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i16), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $h0 = COPY %2(i16) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -205,15 +205,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -232,15 +232,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (s8)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr8 = LDRBpre [[COPY]], 4 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.bsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s8)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i8)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -259,15 +259,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $s0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s16)) - $s0 = COPY %2(s32) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i32), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i16)) + $s0 = COPY %2(i32) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -286,15 +286,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (s16)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr16 = LDRHpre [[COPY]], 4 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.hsub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s16)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i16)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 @@ -313,15 +313,15 @@ body: | ; CHECK: liveins: $d0, $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpre [[COPY]], 4 :: (load (s32)) + ; CHECK-NEXT: early-clobber %3:gpr64sp, %4:fpr32 = LDRSpre [[COPY]], 4 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr64 = SUBREG_TO_REG %4, %subreg.ssub ; CHECK-NEXT: $d0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 4 - %2:fpr(s64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (s32)) - $d0 = COPY %2(s64) + %1:gpr(i64) = G_CONSTANT i64 4 + %2:fpr(i64), %3:gpr(p0) = G_INDEXED_LOAD %0:gpr, %1:gpr, 1 :: (load (i32)) + $d0 = COPY %2(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir index 1ca06aa2c70ea..b047f7acac6b9 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-frint-nofp16.mir @@ -173,7 +173,7 @@ body: | ; CHECK-NEXT: $q0 = COPY [[INSvi16lane6]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<8 x f16>) = COPY $q0 - %2:fpr(f16), %3:fpr(f16), %4:fpr(f16), %5:fpr(f16), %6:fpr(f16), %7:fpr(f16), %8:fpr(f16), %9:fpr(f16) = G_UNMERGE_VALUES %0(<8 x s16>) + %2:fpr(f16), %3:fpr(f16), %4:fpr(f16), %5:fpr(f16), %6:fpr(f16), %7:fpr(f16), %8:fpr(f16), %9:fpr(f16) = G_UNMERGE_VALUES %0(<8 x f16>) %32:fpr(f32) = G_FPEXT %2(f16) %33:fpr(f32) = G_FRINT %32 %10:fpr(f16) = G_FPTRUNC %33(f32) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir index caa1f7e7ef19b..a6521f730bb9c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-large.mir @@ -41,9 +41,9 @@ body: | ; STATIC-NEXT: [[MOVKXi4:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi3]], target-flags(aarch64-g2, aarch64-nc) @foo2, 32 ; STATIC-NEXT: [[MOVKXi5:%[0-9]+]]:gpr64 = MOVKXi [[MOVKXi4]], target-flags(aarch64-g3) @foo2, 48 ; STATIC-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[MOVKXi5]] - ; STATIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; STATIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; STATIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; STATIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; STATIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; STATIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; STATIC-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; STATIC-NEXT: $w0 = COPY [[ADDWrr]] ; STATIC-NEXT: RET_ReallyLR implicit $w0 @@ -53,21 +53,21 @@ body: | ; PIC-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY [[MOVaddr]] ; PIC-NEXT: [[MOVaddr1:%[0-9]+]]:gpr64common = MOVaddr target-flags(aarch64-page) @foo2, target-flags(aarch64-pageoff, aarch64-nc) @foo2 ; PIC-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[MOVaddr1]] - ; PIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; PIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; PIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; PIC-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; PIC-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; PIC-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; PIC-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; PIC-NEXT: $w0 = COPY [[ADDWrr]] ; PIC-NEXT: RET_ReallyLR implicit $w0 - %1:gpr(s32) = G_CONSTANT i32 0 + %1:gpr(i32) = G_CONSTANT i32 0 %4:gpr(p0) = G_GLOBAL_VALUE @foo1 %3:gpr(p0) = COPY %4(p0) %7:gpr(p0) = G_GLOBAL_VALUE @foo2 %6:gpr(p0) = COPY %7(p0) %0:gpr(p0) = G_FRAME_INDEX %stack.0.retval - G_STORE %1(s32), %0(p0) :: (store (s32) into %ir.retval) - %2:gpr(i32) = G_LOAD %3(p0) :: (load (s32) from @foo1) - %5:gpr(i32) = G_LOAD %6(p0) :: (load (s32) from @foo2) + G_STORE %1(i32), %0(p0) :: (store (i32) into %ir.retval) + %2:gpr(i32) = G_LOAD %3(p0) :: (load (i32) from @foo1) + %5:gpr(i32) = G_LOAD %6(p0) :: (load (i32) from @foo2) %8:gpr(i32) = G_ADD %2, %5 $w0 = COPY %8(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir index 65e85f37c21e3..1ba04037aa133 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-gv-cmodel-tiny.mir @@ -34,21 +34,21 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY [[ADR]] ; CHECK-NEXT: [[ADR1:%[0-9]+]]:gpr64 = ADR @foo2 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[ADR1]] - ; CHECK-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (s32) into %ir.retval) - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from @foo1) - ; CHECK-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (s32) from @foo2) + ; CHECK-NEXT: STRWui $wzr, %stack.0.retval, 0 :: (store (i32) into %ir.retval) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from @foo1) + ; CHECK-NEXT: [[LDRWui1:%[0-9]+]]:gpr32 = LDRWui [[COPY1]], 0 :: (load (i32) from @foo2) ; CHECK-NEXT: [[ADDWrr:%[0-9]+]]:gpr32 = ADDWrr [[LDRWui]], [[LDRWui1]] ; CHECK-NEXT: $w0 = COPY [[ADDWrr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %1:gpr(s32) = G_CONSTANT i32 0 + %1:gpr(i32) = G_CONSTANT i32 0 %4:gpr(p0) = G_GLOBAL_VALUE @foo1 %3:gpr(p0) = COPY %4(p0) %7:gpr(p0) = G_GLOBAL_VALUE @foo2 %6:gpr(p0) = COPY %7(p0) %0:gpr(p0) = G_FRAME_INDEX %stack.0.retval - G_STORE %1(s32), %0(p0) :: (store (s32) into %ir.retval) - %2:gpr(i32) = G_LOAD %3(p0) :: (load (s32) from @foo1) - %5:gpr(i32) = G_LOAD %6(p0) :: (load (s32) from @foo2) + G_STORE %1(i32), %0(p0) :: (store (i32) into %ir.retval) + %2:gpr(i32) = G_LOAD %3(p0) :: (load (i32) from @foo1) + %5:gpr(i32) = G_LOAD %6(p0) :: (load (i32) from @foo2) %8:gpr(i32) = G_ADD %2, %5 $w0 = COPY %8(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir index 99e864a287f2b..d7efa669bf35c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-hint.mir @@ -19,9 +19,9 @@ body: | ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 - $w1 = COPY %copy_assert_zext(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_zext:gpr(i32) = G_ASSERT_ZEXT %copy, 16 + $w1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $w1 ... @@ -40,9 +40,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $s1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $s1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 - $s1 = COPY %copy_assert_zext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_zext:fpr(i32) = G_ASSERT_ZEXT %copy, 16 + $s1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $s1 ... @@ -61,9 +61,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_zext:fpr(s32) = G_ASSERT_ZEXT %copy, 16 - $w1 = COPY %copy_assert_zext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_zext:fpr(i32) = G_ASSERT_ZEXT %copy, 16 + $w1 = COPY %copy_assert_zext(i32) RET_ReallyLR implicit $w1 ... @@ -85,10 +85,10 @@ body: | ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 ; CHECK-NEXT: $w1 = COPY %copy_with_rc ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_zext:gpr(s32) = G_ASSERT_ZEXT %copy, 16 - %copy_with_rc:gpr32sp(s32) = COPY $w2 - $w1 = COPY %copy_with_rc(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_zext:gpr(i32) = G_ASSERT_ZEXT %copy, 16 + %copy_with_rc:gpr32sp(i32) = COPY $w2 + $w1 = COPY %copy_with_rc(i32) RET_ReallyLR implicit $w1 ... @@ -107,9 +107,9 @@ body: | ; CHECK-NEXT: %copy:gpr32 = COPY $w0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 - $w1 = COPY %copy_assert_sext(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_sext:gpr(i32) = G_ASSERT_SEXT %copy, 16 + $w1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $w1 ... @@ -128,9 +128,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $s1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $s1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 - $s1 = COPY %copy_assert_sext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_sext:fpr(i32) = G_ASSERT_SEXT %copy, 16 + $s1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $s1 ... @@ -149,9 +149,9 @@ body: | ; CHECK-NEXT: %copy:fpr32 = COPY $s0 ; CHECK-NEXT: $w1 = COPY %copy ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:fpr(s32) = COPY $s0 - %copy_assert_sext:fpr(s32) = G_ASSERT_SEXT %copy, 16 - $w1 = COPY %copy_assert_sext(s32) + %copy:fpr(i32) = COPY $s0 + %copy_assert_sext:fpr(i32) = G_ASSERT_SEXT %copy, 16 + $w1 = COPY %copy_assert_sext(i32) RET_ReallyLR implicit $w1 ... @@ -173,8 +173,8 @@ body: | ; CHECK-NEXT: %copy_with_rc:gpr32sp = COPY $w2 ; CHECK-NEXT: $w1 = COPY %copy_with_rc ; CHECK-NEXT: RET_ReallyLR implicit $w1 - %copy:gpr(s32) = COPY $w0 - %copy_assert_sext:gpr(s32) = G_ASSERT_SEXT %copy, 16 - %copy_with_rc:gpr32sp(s32) = COPY $w2 - $w1 = COPY %copy_with_rc(s32) + %copy:gpr(i32) = COPY $w0 + %copy_assert_sext:gpr(i32) = G_ASSERT_SEXT %copy, 16 + %copy_with_rc:gpr32sp(i32) = COPY $w2 + $w1 = COPY %copy_with_rc(i32) RET_ReallyLR implicit $w1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir index 07e2e189b4c03..798326206bd28 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir @@ -41,8 +41,8 @@ body: | ; CHECK-TINY-NEXT: {{ $}} ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1234 ; CHECK-TINY-NEXT: $w0 = COPY [[MOVi32imm]] - %0(s32) = G_CONSTANT i32 -1234 - $w0 = COPY %0(s32) + %0(i32) = G_CONSTANT i32 -1234 + $w0 = COPY %0(i32) ... --- @@ -71,8 +71,8 @@ body: | ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234 ; CHECK-TINY-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-TINY-NEXT: $x0 = COPY [[SUBREG_TO_REG]] - %0(s64) = G_CONSTANT i64 1234 - $x0 = COPY %0(s64) + %0(i64) = G_CONSTANT i64 1234 + $x0 = COPY %0(i64) ... # 64b FP immediates need to be loaded. diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir index 78d86a6821877..04d5ce0160b73 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-extract.mir @@ -21,13 +21,13 @@ body: | ; CHECK-NEXT: [[BFMXri1:%[0-9]+]]:gpr64 = BFMXri [[DEF]], [[SUBREG_TO_REG1]], 51, 31 ; CHECK-NEXT: $x0 = COPY [[BFMXri]] ; CHECK-NEXT: $x1 = COPY [[BFMXri1]] - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1:gpr(s64) = G_IMPLICIT_DEF + %1:gpr(i64) = G_IMPLICIT_DEF - %2:gpr(s64) = G_INSERT %1, %0, 0 + %2:gpr(i64) = G_INSERT %1, %0, 0 - %3:gpr(s64) = G_INSERT %1, %0, 13 + %3:gpr(i64) = G_INSERT %1, %0, 13 $x0 = COPY %2 $x1 = COPY %3 @@ -50,14 +50,14 @@ body: | ; CHECK-NEXT: [[BFMWri1:%[0-9]+]]:gpr32 = BFMWri [[BFMWri]], [[COPY]], 16, 15 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[BFMWri1]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %1:gpr(s32) = COPY $w0 - %2:gpr(s32) = COPY $w1 - %3:gpr(s16) = G_TRUNC %1(s32) - %4:gpr(s16) = G_TRUNC %1(s32) - %5:gpr(s32) = G_IMPLICIT_DEF - %6:gpr(s32) = G_INSERT %5, %3(s16), 0 - %7:gpr(s32) = G_INSERT %6, %4(s16), 16 - %0:gpr(s32) = COPY %7(s32) + %1:gpr(i32) = COPY $w0 + %2:gpr(i32) = COPY $w1 + %3:gpr(i16) = G_TRUNC %1(i32) + %4:gpr(i16) = G_TRUNC %1(i32) + %5:gpr(i32) = G_IMPLICIT_DEF + %6:gpr(i32) = G_INSERT %5, %3(i16), 0 + %7:gpr(i32) = G_INSERT %6, %4(i16), 16 + %0:gpr(i32) = COPY %7(i32) $w0 = COPY %0 ... @@ -80,11 +80,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[UBFMXri1]].sub_32 ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: $w1 = COPY [[COPY2]] - %0:gpr(s64) = COPY $x0 + %0:gpr(i64) = COPY $x0 - %1:gpr(s32) = G_EXTRACT %0, 0 + %1:gpr(i32) = G_EXTRACT %0, 0 - %2:gpr(s32) = G_EXTRACT %0, 13 + %2:gpr(i32) = G_EXTRACT %0, 13 $w0 = COPY %1 $w1 = COPY %2 @@ -111,11 +111,11 @@ body: | ; CHECK-NEXT: [[COPY3:%[0-9]+]]:fpr32 = COPY [[UBFMWri1]] ; CHECK-NEXT: [[COPY4:%[0-9]+]]:fpr16 = COPY [[COPY3]].hsub ; CHECK-NEXT: $h1 = COPY [[COPY4]] - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1:gpr(s16) = G_EXTRACT %0, 0 + %1:gpr(i16) = G_EXTRACT %0, 0 - %2:gpr(s16) = G_EXTRACT %0, 15 + %2:gpr(i16) = G_EXTRACT %0, 15 $h0 = COPY %1 $h1 = COPY %2 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir index e761c3a808980..e6252a30f2651 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir @@ -18,13 +18,13 @@ body: | ; CHECK-NEXT: [[INSvi8gpr:%[0-9]+]]:fpr128 = INSvi8gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi8gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<16 x s8>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<16 x s8>) = G_INSERT_VECTOR_ELT %1, %4:gpr(s32), %3:gpr(s64) - $q0 = COPY %2(<16 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<16 x i8>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<16 x i8>) = G_INSERT_VECTOR_ELT %1, %4:gpr(i32), %3:gpr(i64) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -49,12 +49,12 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi8gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<8 x s8>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %trunc(s8), %3(s64) - $d0 = COPY %2(<8 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<8 x i8>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<8 x i8>) = G_INSERT_VECTOR_ELT %1, %trunc(i8), %3(i64) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -79,13 +79,13 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi8gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s8) = G_TRUNC %0 - %1:fpr(<8 x s8>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %4(s32), %3(s64) - $d0 = COPY %2(<8 x s8>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i8) = G_TRUNC %0 + %1:fpr(<8 x i8>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<8 x i8>) = G_INSERT_VECTOR_ELT %1, %4(i32), %3(i64) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -107,13 +107,13 @@ body: | ; CHECK-NEXT: [[INSvi16gpr:%[0-9]+]]:fpr128 = INSvi16gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi16gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s16) = G_TRUNC %0 - %1:fpr(<8 x s16>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<8 x s16>) = G_INSERT_VECTOR_ELT %1, %4:gpr(s32), %3:gpr(s64) - $q0 = COPY %2(<8 x s16>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i16) = G_TRUNC %0 + %1:fpr(<8 x i16>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<8 x i16>) = G_INSERT_VECTOR_ELT %1, %4:gpr(i32), %3:gpr(i64) + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -165,11 +165,11 @@ body: | ; CHECK-NEXT: [[INSvi32lane:%[0-9]+]]:fpr128 = INSvi32lane [[COPY1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s32) = COPY $s0 - %1:fpr(<4 x s32>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $q0 = COPY %2(<4 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(<4 x i32>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -191,11 +191,11 @@ body: | ; CHECK-NEXT: [[INSvi32gpr:%[0-9]+]]:fpr128 = INSvi32gpr [[COPY1]], 1, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi32gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s32) = COPY $w0 - %1:fpr(<4 x s32>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $q0 = COPY %2(<4 x s32>) + %0:gpr(i32) = COPY $w0 + %1:fpr(<4 x i32>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -220,13 +220,13 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi16gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %trunc:gpr(s16) = G_TRUNC %0 - %1:fpr(<4 x s16>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %4:gpr(s32) = G_ANYEXT %trunc - %2:fpr(<4 x s16>) = G_INSERT_VECTOR_ELT %1, %4(s32), %3(s64) - $d0 = COPY %2(<4 x s16>) + %0:gpr(i32) = COPY $w0 + %trunc:gpr(i16) = G_TRUNC %0 + %1:fpr(<4 x i16>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %4:gpr(i32) = G_ANYEXT %trunc + %2:fpr(<4 x i16>) = G_INSERT_VECTOR_ELT %1, %4(i32), %3(i64) + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -250,11 +250,11 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[COPY1]], 1, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(s64) = COPY $d0 - %1:fpr(<2 x s64>) = COPY $q1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %1, %0(s64), %3(s64) - $q0 = COPY %2(<2 x s64>) + %0:fpr(i64) = COPY $d0 + %1:fpr(<2 x i64>) = COPY $q1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i64>) = G_INSERT_VECTOR_ELT %1, %0(i64), %3(i64) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -276,11 +276,11 @@ body: | ; CHECK-NEXT: [[INSvi64gpr:%[0-9]+]]:fpr128 = INSvi64gpr [[COPY1]], 0, [[COPY]] ; CHECK-NEXT: $q0 = COPY [[INSvi64gpr]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:gpr(s64) = COPY $x0 - %1:fpr(<2 x s64>) = COPY $q0 - %3:gpr(s64) = G_CONSTANT i64 0 - %2:fpr(<2 x s64>) = G_INSERT_VECTOR_ELT %1, %0(s64), %3(s64) - $q0 = COPY %2(<2 x s64>) + %0:gpr(i64) = COPY $x0 + %1:fpr(<2 x i64>) = COPY $q0 + %3:gpr(i64) = G_CONSTANT i64 0 + %2:fpr(<2 x i64>) = G_INSERT_VECTOR_ELT %1, %0(i64), %3(i64) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -307,11 +307,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi32lane]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(s32) = COPY $s0 - %1:fpr(<2 x s32>) = COPY $d1 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $d0 = COPY %2(<2 x s32>) + %0:fpr(i32) = COPY $s0 + %1:fpr(<2 x i32>) = COPY $d1 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -336,11 +336,11 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi32gpr]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:gpr(s32) = COPY $w0 - %1:fpr(<2 x s32>) = COPY $d0 - %3:gpr(s64) = G_CONSTANT i64 1 - %2:fpr(<2 x s32>) = G_INSERT_VECTOR_ELT %1, %0(s32), %3(s64) - $d0 = COPY %2(<2 x s32>) + %0:gpr(i32) = COPY $w0 + %1:fpr(<2 x i32>) = COPY $d0 + %3:gpr(i64) = G_CONSTANT i64 1 + %2:fpr(<2 x i32>) = G_INSERT_VECTOR_ELT %1, %0(i32), %3(i64) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir index e50f0fd21e7a9..ac5575b88fc31 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-int-ptr-casts.mir @@ -30,7 +30,7 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64all = COPY $x0 ; CHECK-NEXT: $x0 = COPY [[COPY]] - %0(s64) = COPY $x0 + %0(i64) = COPY $x0 %1(p0) = G_INTTOPTR %0 $x0 = COPY %1(p0) ... @@ -52,8 +52,8 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x0 ; CHECK-NEXT: $x0 = COPY [[COPY]] %0(p0) = COPY $x0 - %1(s64) = G_PTRTOINT %0 - $x0 = COPY %1(s64) + %1(i64) = G_PTRTOINT %0 + $x0 = COPY %1(i64) ... --- @@ -104,8 +104,8 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $h0 %ptr:gpr(p0) = COPY $x0 %ptr2int:gpr(i64) = G_PTRTOINT %ptr(p0) - %int:gpr(s16) = G_TRUNC %ptr2int(i64) - $h0 = COPY %int(s16) + %int:gpr(i16) = G_TRUNC %ptr2int(i64) + $h0 = COPY %int(i16) RET_ReallyLR implicit $h0 ... @@ -131,8 +131,8 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $b0 %ptr:gpr(p0) = COPY $x0 %ptr2int:gpr(i64) = G_PTRTOINT %ptr(p0) - %int:gpr(s8) = G_TRUNC %ptr2int(i64) - $b0 = COPY %int(s8) + %int:gpr(i8) = G_TRUNC %ptr2int(i64) + $b0 = COPY %int(i8) RET_ReallyLR implicit $b0 ... @@ -179,10 +179,10 @@ body: | ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]].dsub ; CHECK-NEXT: $x0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %1:fpr(<2 x s64>) = COPY $q0 - %2:fpr(<2 x p0>) = G_INTTOPTR %1(<2 x s64>) - %4:gpr(s64) = G_CONSTANT i64 0 - %3:fpr(p0) = G_EXTRACT_VECTOR_ELT %2(<2 x p0>), %4(s64) + %1:fpr(<2 x i64>) = COPY $q0 + %2:fpr(<2 x p0>) = G_INTTOPTR %1(<2 x i64>) + %4:gpr(i64) = G_CONSTANT i64 0 + %3:fpr(p0) = G_EXTRACT_VECTOR_ELT %2(<2 x p0>), %4(i64) $x0 = COPY %3(p0) RET_ReallyLR implicit $x0 ... @@ -202,7 +202,7 @@ body: | ; CHECK-NEXT: $q0 = COPY %ptr ; CHECK-NEXT: RET_ReallyLR implicit $q0 %ptr:fpr(<2 x p0>) = COPY $q0 - %int:fpr(<2 x s64>) = G_PTRTOINT %ptr(<2 x p0>) - $q0 = COPY %int(<2 x s64>) + %int:fpr(<2 x i64>) = G_PTRTOINT %ptr(<2 x p0>) + $q0 = COPY %int(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir index c63f99218f05c..cc904bca9bf88 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-aarch64-hint.mir @@ -24,6 +24,6 @@ body: | bb.0: liveins: $w0 - %0(s32) = G_CONSTANT i32 1 + %0(i32) = G_CONSTANT i32 1 G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.hint), %0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir index 7d17336ad7543..06aa66678f071 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-intrinsic-crypto-aesmc.mir @@ -20,9 +20,9 @@ body: | ; CHECK-NEXT: [[AESErr:%[0-9]+]]:fpr128 = AESErr [[COPY]], [[COPY1]] ; CHECK-NEXT: [[AESMCrrTied:%[0-9]+]]:fpr128 = AESMCrrTied [[AESErr]] ; CHECK-NEXT: $q0 = COPY [[AESMCrrTied]] - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aese), %0, %1 - %3:fpr(<16 x s8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aesmc), %2 - $q0 = COPY %3(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aese), %0, %1 + %3:fpr(<16 x i8>) = G_INTRINSIC intrinsic(@llvm.aarch64.crypto.aesmc), %2 + $q0 = COPY %3(<16 x i8>) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir index 92121b0b42162..0bd939e217e54 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-jump-table-brjt-constrain.mir @@ -25,7 +25,7 @@ body: | ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.1(0x40000000) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64common = IMPLICIT_DEF - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64common = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[SUBREG_TO_REG]], 8, 0, implicit-def $nzcv ; CHECK-NEXT: Bcc 8, %bb.3, implicit $nzcv @@ -47,16 +47,16 @@ body: | ; CHECK-NEXT: RET_ReallyLR bb.1: %1:gpr(p0) = G_IMPLICIT_DEF - %5:gpr(s64) = G_ZEXTLOAD %1(p0) :: (load (s8)) - %7:gpr(s64) = G_CONSTANT i64 8 - %16:gpr(s32) = G_ICMP intpred(ugt), %5(s64), %7 + %5:gpr(i64) = G_ZEXTLOAD %1(p0) :: (load (i8)) + %7:gpr(i64) = G_CONSTANT i64 8 + %16:gpr(i32) = G_ICMP intpred(ugt), %5(i64), %7 G_BRCOND %16, %bb.4 bb.2: successors: %bb.3, %bb.4 %9:gpr(p0) = G_JUMP_TABLE %jump-table.0 - G_BRJT %9(p0), %jump-table.0, %5(s64) + G_BRJT %9(p0), %jump-table.0, %5(i64) bb.3: G_BR %bb.4 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir index 933dcb9628314..7d4b72d428fdf 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld2.mir @@ -13,16 +13,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov8b:%[0-9]+]]:dd = LD2Twov8b %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD2Twov8b:%[0-9]+]]:dd = LD2Twov8b %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov8b]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov8b]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s8>), %dst2:fpr(<8 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x s64>)) - $d0 = COPY %dst1(<8 x s8>) - $d1 = COPY %dst2(<8 x s8>) + %dst1:fpr(<8 x i8>), %dst2:fpr(<8 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x i64>)) + $d0 = COPY %dst1(<8 x i8>) + $d1 = COPY %dst2(<8 x i8>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -37,16 +37,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov16b:%[0-9]+]]:qq = LD2Twov16b %ptr :: (load (<16 x s64>)) + ; CHECK-NEXT: [[LD2Twov16b:%[0-9]+]]:qq = LD2Twov16b %ptr :: (load (<16 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov16b]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov16b]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<16 x s8>), %dst2:fpr(<16 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<16 x s64>)) - $q0 = COPY %dst1(<16 x s8>) - $q1 = COPY %dst2(<16 x s8>) + %dst1:fpr(<16 x i8>), %dst2:fpr(<16 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<16 x i64>)) + $q0 = COPY %dst1(<16 x i8>) + $q1 = COPY %dst2(<16 x i8>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -61,16 +61,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov4h:%[0-9]+]]:dd = LD2Twov4h %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD2Twov4h:%[0-9]+]]:dd = LD2Twov4h %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov4h]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov4h]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s16>), %dst2:fpr(<4 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x s64>)) - $d0 = COPY %dst1(<4 x s16>) - $d1 = COPY %dst2(<4 x s16>) + %dst1:fpr(<4 x i16>), %dst2:fpr(<4 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x i64>)) + $d0 = COPY %dst1(<4 x i16>) + $d1 = COPY %dst2(<4 x i16>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -85,16 +85,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov8h:%[0-9]+]]:qq = LD2Twov8h %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD2Twov8h:%[0-9]+]]:qq = LD2Twov8h %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov8h]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov8h]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s16>), %dst2:fpr(<8 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x s64>)) - $q0 = COPY %dst1(<8 x s16>) - $q1 = COPY %dst2(<8 x s16>) + %dst1:fpr(<8 x i16>), %dst2:fpr(<8 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<8 x i64>)) + $q0 = COPY %dst1(<8 x i16>) + $q1 = COPY %dst2(<8 x i16>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -109,16 +109,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov2s:%[0-9]+]]:dd = LD2Twov2s %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD2Twov2s:%[0-9]+]]:dd = LD2Twov2s %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD2Twov2s]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD2Twov2s]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s32>), %dst2:fpr(<2 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x s64>)) - $d0 = COPY %dst1(<2 x s32>) - $d1 = COPY %dst2(<2 x s32>) + %dst1:fpr(<2 x i32>), %dst2:fpr(<2 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x i64>)) + $d0 = COPY %dst1(<2 x i32>) + $d1 = COPY %dst2(<2 x i32>) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -133,16 +133,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov4s:%[0-9]+]]:qq = LD2Twov4s %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD2Twov4s:%[0-9]+]]:qq = LD2Twov4s %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov4s]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov4s]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s32>), %dst2:fpr(<4 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x s64>)) - $q0 = COPY %dst1(<4 x s32>) - $q1 = COPY %dst2(<4 x s32>) + %dst1:fpr(<4 x i32>), %dst2:fpr(<4 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<4 x i64>)) + $q0 = COPY %dst1(<4 x i32>) + $q1 = COPY %dst2(<4 x i32>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -157,16 +157,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD2Twov2d:%[0-9]+]]:qq = LD2Twov2d %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD2Twov2d:%[0-9]+]]:qq = LD2Twov2d %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD2Twov2d]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD2Twov2d]].qsub1 ; CHECK-NEXT: $q0 = COPY %dst1 ; CHECK-NEXT: $q1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s64>), %dst2:fpr(<2 x s64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x s64>)) - $q0 = COPY %dst1(<2 x s64>) - $q1 = COPY %dst2(<2 x s64>) + %dst1:fpr(<2 x i64>), %dst2:fpr(<2 x i64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (<2 x i64>)) + $q0 = COPY %dst1(<2 x i64>) + $q1 = COPY %dst2(<2 x i64>) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -205,16 +205,16 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1Twov1d:%[0-9]+]]:dd = LD1Twov1d %ptr :: (load (s64)) + ; CHECK-NEXT: [[LD1Twov1d:%[0-9]+]]:dd = LD1Twov1d %ptr :: (load (i64)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD1Twov1d]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD1Twov1d]].dsub1 ; CHECK-NEXT: $d0 = COPY %dst1 ; CHECK-NEXT: $d1 = COPY %dst2 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(s64), %dst2:fpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (s64)) - $d0 = COPY %dst1(s64) - $d1 = COPY %dst2(s64) + %dst1:fpr(i64), %dst2:fpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld2), %ptr(p0) :: (load (i64)) + $d0 = COPY %dst1(i64) + $d1 = COPY %dst2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir index 03e271e15e991..cd15b7b4b0e2d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ld4.mir @@ -13,7 +13,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv8b:%[0-9]+]]:dddd = LD4Fourv8b %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD4Fourv8b:%[0-9]+]]:dddd = LD4Fourv8b %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv8b]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv8b]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv8b]].dsub2 @@ -24,11 +24,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s8>), %dst2:fpr(<8 x s8>), %dst3:fpr(<8 x s8>), %dst4:fpr(<8 x s8>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x s64>)) - $d0 = COPY %dst1(<8 x s8>) - $d1 = COPY %dst2(<8 x s8>) - $d2 = COPY %dst3(<8 x s8>) - $d3 = COPY %dst4(<8 x s8>) + %dst1:fpr(<8 x i8>), %dst2:fpr(<8 x i8>), %dst3:fpr(<8 x i8>), %dst4:fpr(<8 x i8>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x i64>)) + $d0 = COPY %dst1(<8 x i8>) + $d1 = COPY %dst2(<8 x i8>) + $d2 = COPY %dst3(<8 x i8>) + $d3 = COPY %dst4(<8 x i8>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -43,7 +43,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv16b:%[0-9]+]]:qqqq = LD4Fourv16b %ptr :: (load (<16 x s64>)) + ; CHECK-NEXT: [[LD4Fourv16b:%[0-9]+]]:qqqq = LD4Fourv16b %ptr :: (load (<16 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv16b]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv16b]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv16b]].qsub2 @@ -54,11 +54,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<16 x s8>), %dst2:fpr(<16 x s8>), %dst3:fpr(<16 x s8>), %dst4:fpr(<16 x s8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<16 x s64>)) - $q0 = COPY %dst1(<16 x s8>) - $q1 = COPY %dst2(<16 x s8>) - $q2 = COPY %dst3(<16 x s8>) - $q3 = COPY %dst4(<16 x s8>) + %dst1:fpr(<16 x i8>), %dst2:fpr(<16 x i8>), %dst3:fpr(<16 x i8>), %dst4:fpr(<16 x i8>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<16 x i64>)) + $q0 = COPY %dst1(<16 x i8>) + $q1 = COPY %dst2(<16 x i8>) + $q2 = COPY %dst3(<16 x i8>) + $q3 = COPY %dst4(<16 x i8>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -73,7 +73,7 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv4h:%[0-9]+]]:dddd = LD4Fourv4h %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD4Fourv4h:%[0-9]+]]:dddd = LD4Fourv4h %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv4h]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv4h]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv4h]].dsub2 @@ -84,11 +84,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s16>), %dst2:fpr(<4 x s16>), %dst3:fpr(<4 x s16>), %dst4:fpr(<4 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x s64>)) - $d0 = COPY %dst1(<4 x s16>) - $d1 = COPY %dst2(<4 x s16>) - $d2 = COPY %dst3(<4 x s16>) - $d3 = COPY %dst4(<4 x s16>) + %dst1:fpr(<4 x i16>), %dst2:fpr(<4 x i16>), %dst3:fpr(<4 x i16>), %dst4:fpr(<4 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x i64>)) + $d0 = COPY %dst1(<4 x i16>) + $d1 = COPY %dst2(<4 x i16>) + $d2 = COPY %dst3(<4 x i16>) + $d3 = COPY %dst4(<4 x i16>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -103,7 +103,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv8h:%[0-9]+]]:qqqq = LD4Fourv8h %ptr :: (load (<8 x s64>)) + ; CHECK-NEXT: [[LD4Fourv8h:%[0-9]+]]:qqqq = LD4Fourv8h %ptr :: (load (<8 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv8h]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv8h]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv8h]].qsub2 @@ -114,11 +114,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<8 x s16>), %dst2:fpr(<8 x s16>), %dst3:fpr(<8 x s16>), %dst4:fpr(<8 x s16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x s64>)) - $q0 = COPY %dst1(<8 x s16>) - $q1 = COPY %dst2(<8 x s16>) - $q2 = COPY %dst3(<8 x s16>) - $q3 = COPY %dst4(<8 x s16>) + %dst1:fpr(<8 x i16>), %dst2:fpr(<8 x i16>), %dst3:fpr(<8 x i16>), %dst4:fpr(<8 x i16>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<8 x i64>)) + $q0 = COPY %dst1(<8 x i16>) + $q1 = COPY %dst2(<8 x i16>) + $q2 = COPY %dst3(<8 x i16>) + $q3 = COPY %dst4(<8 x i16>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -133,7 +133,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv2s:%[0-9]+]]:dddd = LD4Fourv2s %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD4Fourv2s:%[0-9]+]]:dddd = LD4Fourv2s %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD4Fourv2s]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD4Fourv2s]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD4Fourv2s]].dsub2 @@ -144,11 +144,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s32>), %dst2:fpr(<2 x s32>), %dst3:fpr(<2 x s32>), %dst4:fpr(<2 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x s64>)) - $d0 = COPY %dst1(<2 x s32>) - $d1 = COPY %dst2(<2 x s32>) - $d2 = COPY %dst3(<2 x s32>) - $d3 = COPY %dst4(<2 x s32>) + %dst1:fpr(<2 x i32>), %dst2:fpr(<2 x i32>), %dst3:fpr(<2 x i32>), %dst4:fpr(<2 x i32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x i64>)) + $d0 = COPY %dst1(<2 x i32>) + $d1 = COPY %dst2(<2 x i32>) + $d2 = COPY %dst3(<2 x i32>) + $d3 = COPY %dst4(<2 x i32>) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- @@ -163,7 +163,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv4s:%[0-9]+]]:qqqq = LD4Fourv4s %ptr :: (load (<4 x s64>)) + ; CHECK-NEXT: [[LD4Fourv4s:%[0-9]+]]:qqqq = LD4Fourv4s %ptr :: (load (<4 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv4s]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv4s]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv4s]].qsub2 @@ -174,11 +174,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<4 x s32>), %dst2:fpr(<4 x s32>), %dst3:fpr(<4 x s32>), %dst4:fpr(<4 x s32>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x s64>)) - $q0 = COPY %dst1(<4 x s32>) - $q1 = COPY %dst2(<4 x s32>) - $q2 = COPY %dst3(<4 x s32>) - $q3 = COPY %dst4(<4 x s32>) + %dst1:fpr(<4 x i32>), %dst2:fpr(<4 x i32>), %dst3:fpr(<4 x i32>), %dst4:fpr(<4 x i32>)= G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<4 x i64>)) + $q0 = COPY %dst1(<4 x i32>) + $q1 = COPY %dst2(<4 x i32>) + $q2 = COPY %dst3(<4 x i32>) + $q3 = COPY %dst4(<4 x i32>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -193,7 +193,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD4Fourv2d:%[0-9]+]]:qqqq = LD4Fourv2d %ptr :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LD4Fourv2d:%[0-9]+]]:qqqq = LD4Fourv2d %ptr :: (load (<2 x i64>)) ; CHECK-NEXT: %dst1:fpr128 = COPY [[LD4Fourv2d]].qsub0 ; CHECK-NEXT: %dst2:fpr128 = COPY [[LD4Fourv2d]].qsub1 ; CHECK-NEXT: %dst3:fpr128 = COPY [[LD4Fourv2d]].qsub2 @@ -204,11 +204,11 @@ body: | ; CHECK-NEXT: $q3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(<2 x s64>), %dst2:fpr(<2 x s64>), %dst3:fpr(<2 x s64>), %dst4:fpr(<2 x s64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x s64>)) - $q0 = COPY %dst1(<2 x s64>) - $q1 = COPY %dst2(<2 x s64>) - $q2 = COPY %dst3(<2 x s64>) - $q3 = COPY %dst4(<2 x s64>) + %dst1:fpr(<2 x i64>), %dst2:fpr(<2 x i64>), %dst3:fpr(<2 x i64>), %dst4:fpr(<2 x i64>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (<2 x i64>)) + $q0 = COPY %dst1(<2 x i64>) + $q1 = COPY %dst2(<2 x i64>) + $q2 = COPY %dst3(<2 x i64>) + $q3 = COPY %dst4(<2 x i64>) RET_ReallyLR implicit $q0, implicit $q1, implicit $q2, implicit $q3 ... --- @@ -253,7 +253,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1Fourv1d:%[0-9]+]]:dddd = LD1Fourv1d %ptr :: (load (s64)) + ; CHECK-NEXT: [[LD1Fourv1d:%[0-9]+]]:dddd = LD1Fourv1d %ptr :: (load (i64)) ; CHECK-NEXT: %dst1:fpr64 = COPY [[LD1Fourv1d]].dsub0 ; CHECK-NEXT: %dst2:fpr64 = COPY [[LD1Fourv1d]].dsub1 ; CHECK-NEXT: %dst3:fpr64 = COPY [[LD1Fourv1d]].dsub2 @@ -264,11 +264,11 @@ body: | ; CHECK-NEXT: $d3 = COPY %dst4 ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 %ptr:gpr(p0) = COPY $x0 - %dst1:fpr(s64), %dst2:fpr(s64), %dst3:fpr(s64), %dst4:fpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (s64)) - $d0 = COPY %dst1(s64) - $d1 = COPY %dst2(s64) - $d2 = COPY %dst3(s64) - $d3 = COPY %dst4(s64) + %dst1:fpr(i64), %dst2:fpr(i64), %dst3:fpr(i64), %dst4:fpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld4), %ptr(p0) :: (load (i64)) + $d0 = COPY %dst1(i64) + $d1 = COPY %dst2(i64) + $d2 = COPY %dst3(i64) + $d3 = COPY %dst4(i64) RET_ReallyLR implicit $d0, implicit $d1, implicit $d2, implicit $d3 ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir index 6526cd977eb55..e86536563ae9e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldaxr-intrin.mir @@ -21,12 +21,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRB:%[0-9]+]]:gpr32 = LDAXRB [[COPY]] :: (volatile load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDAXRB:%[0-9]+]]:gpr32 = LDAXRB [[COPY]] :: (volatile load (i8) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRB]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s8) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i8) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -44,12 +44,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRH:%[0-9]+]]:gpr32 = LDAXRH [[COPY]] :: (volatile load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDAXRH:%[0-9]+]]:gpr32 = LDAXRH [[COPY]] :: (volatile load (i16) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRH]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s16) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i16) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -67,12 +67,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRW:%[0-9]+]]:gpr32 = LDAXRW [[COPY]] :: (volatile load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDAXRW:%[0-9]+]]:gpr32 = LDAXRW [[COPY]] :: (volatile load (i32) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDAXRW]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s32) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i32) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 @@ -90,10 +90,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDAXRX:%[0-9]+]]:gpr64 = LDAXRX [[COPY]] :: (volatile load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDAXRX:%[0-9]+]]:gpr64 = LDAXRX [[COPY]] :: (volatile load (i64) from %ir.addr) ; CHECK-NEXT: $x1 = COPY [[LDAXRX]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (s64) from %ir.addr) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldaxr), %0(p0) :: (volatile load (i64) from %ir.addr) $x1 = COPY %1 RET_ReallyLR implicit $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir index 1eaafd517d986..5a654b3cfffc5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ldxr-intrin.mir @@ -20,13 +20,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRB:%[0-9]+]]:gpr32 = LDXRB [[COPY]] :: (volatile load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDXRB:%[0-9]+]]:gpr32 = LDXRB [[COPY]] :: (volatile load (i8) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRB]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s8) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i8) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 ... @@ -43,13 +43,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRH:%[0-9]+]]:gpr32 = LDXRH [[COPY]] :: (volatile load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDXRH:%[0-9]+]]:gpr32 = LDXRH [[COPY]] :: (volatile load (i16) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRH]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s16) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i16) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 ... @@ -66,13 +66,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRW:%[0-9]+]]:gpr32 = LDXRW [[COPY]] :: (volatile load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDXRW:%[0-9]+]]:gpr32 = LDXRW [[COPY]] :: (volatile load (i32) from %ir.addr) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDXRW]], %subreg.sub_32 ; CHECK-NEXT: $x1 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s32) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i32) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 @@ -90,10 +90,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDXRX:%[0-9]+]]:gpr64 = LDXRX [[COPY]] :: (volatile load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDXRX:%[0-9]+]]:gpr64 = LDXRX [[COPY]] :: (volatile load (i64) from %ir.addr) ; CHECK-NEXT: $x1 = COPY [[LDXRX]] ; CHECK-NEXT: RET_ReallyLR implicit $x1 %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (s64) from %ir.addr) - $x1 = COPY %1(s64) + %1:gpr(i64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), %0(p0) :: (volatile load (i64) from %ir.addr) + $x1 = COPY %1(i64) RET_ReallyLR implicit $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir index b5e204433c4ad..d9712da595d23 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-load-store-vector-of-ptr.mir @@ -35,12 +35,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<2 x s64>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<2 x i64>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR %0:fpr(<2 x p0>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(<2 x s64>) = G_BITCAST %0(<2 x p0>) - G_STORE %2(<2 x s64>), %1(p0) :: (store (<2 x s64>) into %ir.ptr) + %2:fpr(<2 x i64>) = G_BITCAST %0(<2 x p0>) + G_STORE %2(<2 x i64>), %1(p0) :: (store (<2 x i64>) into %ir.ptr) RET_ReallyLR ... @@ -63,12 +63,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %2:fpr(<2 x s64>) = G_LOAD %0(p0) :: (load (<2 x s64>) from %ir.ptr) - %1:fpr(<2 x p0>) = G_BITCAST %2(<2 x s64>) + %2:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x i64>) from %ir.ptr) + %1:fpr(<2 x p0>) = G_BITCAST %2(<2 x i64>) $q0 = COPY %1(<2 x p0>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir index bc094e7703b97..09db59db840ef 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-load.mir @@ -62,11 +62,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 0 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = COPY $x0 - %1(s64) = G_LOAD %0 :: (load (s64) from %ir.addr) - $x0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64) from %ir.addr) + $x0 = COPY %1(i64) ... --- @@ -86,11 +86,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRWui]] %0(p0) = COPY $x0 - %1(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - $w0 = COPY %1(s32) + %1(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -106,11 +106,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s16) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i16) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -130,13 +130,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... --- @@ -152,11 +152,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_LOAD %0 :: (load (s8) from %ir.addr) - $w0 = COPY %1(s32) + %1:gpr(i32) = G_LOAD %0 :: (load (i8) from %ir.addr) + $w0 = COPY %1(i32) ... --- @@ -176,13 +176,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - %2:gpr(s32) = G_ANYEXT %1 - $w0 = COPY %2(s32) + %1(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + %2:gpr(i32) = G_ANYEXT %1 + $w0 = COPY %2(i32) ... --- @@ -204,11 +204,11 @@ body: | ; CHECK-LABEL: name: load_fi_s64_gpr ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui %stack.0.ptr0, 0 :: (load (s64)) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui %stack.0.ptr0, 0 :: (load (i64)) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = G_FRAME_INDEX %stack.0.ptr0 - %1(s64) = G_LOAD %0 :: (load (s64)) - $x0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64)) + $x0 = COPY %1(i64) ... --- @@ -230,12 +230,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 16 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRXui:%[0-9]+]]:gpr64 = LDRXui [[COPY]], 16 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $x0 = COPY [[LDRXui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 128 + %1(i64) = G_CONSTANT i64 128 %2(p0) = G_PTR_ADD %0, %1 - %3(s64) = G_LOAD %2 :: (load (s64) from %ir.addr) + %3(i64) = G_LOAD %2 :: (load (i64) from %ir.addr) $x0 = COPY %3 ... @@ -258,12 +258,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 128 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 128 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRWui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 512 + %1(i64) = G_CONSTANT i64 512 %2(p0) = G_PTR_ADD %0, %1 - %3(s32) = G_LOAD %2 :: (load (s32) from %ir.addr) + %3(i32) = G_LOAD %2 :: (load (i32) from %ir.addr) $w0 = COPY %3 ... @@ -286,14 +286,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 32 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 32 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 64 + %1(i64) = G_CONSTANT i64 64 %2(p0) = G_PTR_ADD %0, %1 - %3(s16) = G_LOAD %2 :: (load (s16) from %ir.addr) - %4:gpr(s32) = G_ANYEXT %3 + %3(i16) = G_LOAD %2 :: (load (i16) from %ir.addr) + %4:gpr(i32) = G_ANYEXT %3 $w0 = COPY %4 ... @@ -316,14 +316,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 1 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 1 :: (load (i8) from %ir.addr) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 1 + %1(i64) = G_CONSTANT i64 1 %2(p0) = G_PTR_ADD %0, %1 - %3(s8) = G_LOAD %2 :: (load (s8) from %ir.addr) - %4:gpr(s32) = G_ANYEXT %3 + %3(i8) = G_LOAD %2 :: (load (i8) from %ir.addr) + %4:gpr(i32) = G_ANYEXT %3 $w0 = COPY %4 ... @@ -344,11 +344,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(s64) = G_LOAD %0 :: (load (s64) from %ir.addr) - $d0 = COPY %1(s64) + %1(i64) = G_LOAD %0 :: (load (i64) from %ir.addr) + $d0 = COPY %1(i64) ... --- @@ -368,11 +368,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 0 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 0 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $s0 = COPY [[LDRSui]] %0(p0) = COPY $x0 - %1(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - $s0 = COPY %1(s32) + %1(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + $s0 = COPY %1(i32) ... --- @@ -392,11 +392,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $h0 = COPY [[LDRHui]] %0(p0) = COPY $x0 - %1(s16) = G_LOAD %0 :: (load (s16) from %ir.addr) - $h0 = COPY %1(s16) + %1(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) + $h0 = COPY %1(i16) ... --- @@ -416,11 +416,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $b0 = COPY [[LDRBui]] %0(p0) = COPY $x0 - %1(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - $b0 = COPY %1(s8) + %1(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + $b0 = COPY %1(i8) ... --- @@ -442,12 +442,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 1 :: (load (s64) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 1 :: (load (i64) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 8 + %1(i64) = G_CONSTANT i64 8 %2(p0) = G_PTR_ADD %0, %1 - %3(s64) = G_LOAD %2 :: (load (s64) from %ir.addr) + %3(i64) = G_LOAD %2 :: (load (i64) from %ir.addr) $d0 = COPY %3 ... @@ -470,12 +470,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 4 :: (load (s32) from %ir.addr) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY]], 4 :: (load (i32) from %ir.addr) ; CHECK-NEXT: $s0 = COPY [[LDRSui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 16 + %1(i64) = G_CONSTANT i64 16 %2(p0) = G_PTR_ADD %0, %1 - %3(s32) = G_LOAD %2 :: (load (s32) from %ir.addr) + %3(i32) = G_LOAD %2 :: (load (i32) from %ir.addr) $s0 = COPY %3 ... @@ -498,12 +498,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 32 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 32 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $h0 = COPY [[LDRHui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 64 + %1(i64) = G_CONSTANT i64 64 %2(p0) = G_PTR_ADD %0, %1 - %3(s16) = G_LOAD %2 :: (load (s16) from %ir.addr) + %3(i16) = G_LOAD %2 :: (load (i16) from %ir.addr) $h0 = COPY %3 ... @@ -526,12 +526,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 32 :: (load (s8) from %ir.addr) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 32 :: (load (i8) from %ir.addr) ; CHECK-NEXT: $b0 = COPY [[LDRBui]] %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 32 + %1(i64) = G_CONSTANT i64 32 %2(p0) = G_PTR_ADD %0, %1 - %3(s8) = G_LOAD %2 :: (load (s8) from %ir.addr) + %3(i8) = G_LOAD %2 :: (load (i8) from %ir.addr) $b0 = COPY %3 ... --- @@ -551,11 +551,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x s32>) from %ir.addr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x i32>) from %ir.addr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] %0(p0) = COPY $x0 - %1(<2 x s32>) = G_LOAD %0 :: (load (<2 x s32>) from %ir.addr) - $d0 = COPY %1(<2 x s32>) + %1(<2 x i32>) = G_LOAD %0 :: (load (<2 x i32>) from %ir.addr) + $d0 = COPY %1(<2 x i32>) ... --- name: load_v2s64 @@ -574,11 +574,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>) from %ir.addr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>) from %ir.addr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] %0(p0) = COPY $x0 - %1(<2 x s64>) = G_LOAD %0 :: (load (<2 x s64>) from %ir.addr) - $q0 = COPY %1(<2 x s64>) + %1(<2 x i64>) = G_LOAD %0 :: (load (<2 x i64>) from %ir.addr) + $q0 = COPY %1(<2 x i64>) ... --- name: load_4xi16 @@ -598,12 +598,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<4 x s16>) from %ir.ptr) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<4 x i16>) from %ir.ptr) ; CHECK-NEXT: $d0 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x s16>) = G_LOAD %0(p0) :: (load (<4 x s16>) from %ir.ptr) - $d0 = COPY %1(<4 x s16>) + %1:fpr(<4 x i16>) = G_LOAD %0(p0) :: (load (<4 x i16>) from %ir.ptr) + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -625,12 +625,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x s32>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x i32>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x s32>) = G_LOAD %0(p0) :: (load (<4 x s32>) from %ir.ptr) - $q0 = COPY %1(<4 x s32>) + %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x i32>) from %ir.ptr) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -652,12 +652,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x s16>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x i16>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<8 x s16>) = G_LOAD %0(p0) :: (load (<8 x s16>) from %ir.ptr) - $q0 = COPY %1(<8 x s16>) + %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x i16>) from %ir.ptr) + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -679,12 +679,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x s8>) from %ir.ptr) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x i8>) from %ir.ptr) ; CHECK-NEXT: $q0 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:gpr(p0) = COPY $x0 - %1:fpr(<16 x s8>) = G_LOAD %0(p0) :: (load (<16 x s8>) from %ir.ptr) - $q0 = COPY %1(<16 x s8>) + %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x i8>) from %ir.ptr) + $q0 = COPY %1(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -710,15 +710,15 @@ body: | ; CHECK: liveins: $w3, $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[LDRHui]], %subreg.hsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %16:fpr(s32) = G_LOAD %0(p0) :: (load (s16)) - %24:gpr(s32) = COPY %16(s32) - $w0 = COPY %24(s32) + %16:fpr(i32) = G_LOAD %0(p0) :: (load (i16)) + %24:gpr(i32) = COPY %16(i32) + $w0 = COPY %24(i32) RET_ReallyLR ... @@ -744,15 +744,15 @@ body: | ; CHECK: liveins: $w3, $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[LDRBui]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR %0:gpr(p0) = COPY $x0 - %16:fpr(s32) = G_LOAD %0(p0) :: (load (s8)) - %24:gpr(s32) = COPY %16(s32) - $w0 = COPY %24(s32) + %16:fpr(i32) = G_LOAD %0(p0) :: (load (i8)) + %24:gpr(i32) = COPY %16(i32) + $w0 = COPY %24(i32) RET_ReallyLR ... @@ -770,16 +770,16 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LD1i32_:%[0-9]+]]:fpr128 = LD1i32 [[COPY]], 0, [[COPY1]] :: (load (s32)) + ; CHECK-NEXT: [[LD1i32_:%[0-9]+]]:fpr128 = LD1i32 [[COPY]], 0, [[COPY1]] :: (load (i32)) ; CHECK-NEXT: $q0 = COPY [[LD1i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_LOAD %1(p0) :: (load (s32)) - %3:gpr(s32) = G_CONSTANT i32 3 - %5:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %0, %2(s32), %5(s64) - $q0 = COPY %4(<4 x s32>) + %2:fpr(i32) = G_LOAD %1(p0) :: (load (i32)) + %3:gpr(i32) = G_CONSTANT i32 3 + %5:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %0, %2(i32), %5(i64) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -798,21 +798,21 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY1]], 0 :: (load (s32)) + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[COPY1]], 0 :: (load (i32)) ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 3 - ; CHECK-NEXT: STRWui [[MOVi32imm]], [[COPY1]], 0 :: (store (s32)) + ; CHECK-NEXT: STRWui [[MOVi32imm]], [[COPY1]], 0 :: (store (i32)) ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], [[LDRSui]], %subreg.ssub ; CHECK-NEXT: [[INSvi32lane:%[0-9]+]]:fpr128 = INSvi32lane [[COPY]], 0, [[INSERT_SUBREG]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - %2:fpr(s32) = G_LOAD %1(p0) :: (load (s32)) - %3:gpr(s32) = G_CONSTANT i32 3 - G_STORE %3(s32), %1(p0) :: (store (s32)) - %5:gpr(s64) = G_CONSTANT i64 0 - %4:fpr(<4 x s32>) = G_INSERT_VECTOR_ELT %0, %2(s32), %5(s64) - $q0 = COPY %4(<4 x s32>) + %2:fpr(i32) = G_LOAD %1(p0) :: (load (i32)) + %3:gpr(i32) = G_CONSTANT i32 3 + G_STORE %3(i32), %1(p0) :: (store (i32)) + %5:gpr(i64) = G_CONSTANT i64 0 + %4:fpr(<4 x i32>) = G_INSERT_VECTOR_ELT %0, %2(i32), %5(i64) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir index 604cb96e38dc3..186f2c94ecdca 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-modf.mir @@ -27,21 +27,21 @@ body: | ; CHECK-NEXT: BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui %stack.0, 0 :: (load (s128) from %stack.0) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui %stack.0, 0 :: (load (i128) from %stack.0) ; CHECK-NEXT: $q0 = COPY [[COPY1]] ; CHECK-NEXT: $q1 = COPY [[LDRQui]] ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 - %0:fpr(s128) = COPY $q0 + %0:fpr(i128) = COPY $q0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $q0 = COPY %0(s128) + $q0 = COPY %0(i128) $x0 = COPY %3(p0) BL &modfl, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $q0, implicit $x0, implicit-def $q0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s128) = COPY $q0 - %2:fpr(s128) = G_LOAD %3(p0) :: (load (s128) from %stack.0) - $q0 = COPY %1(s128) - $q1 = COPY %2(s128) + %1:fpr(i128) = COPY $q0 + %2:fpr(i128) = G_LOAD %3(p0) :: (load (i128) from %stack.0) + $q0 = COPY %1(i128) + $q1 = COPY %2(i128) RET_ReallyLR implicit $q0, implicit $q1 ... --- @@ -72,21 +72,21 @@ body: | ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (i64) from %stack.0) ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $d0 = COPY %0(s64) + $d0 = COPY %0(i64) $x0 = COPY %3(p0) BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s64) = COPY $d0 - %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %1:fpr(i64) = COPY $d0 + %2:fpr(i64) = G_LOAD %3(p0) :: (load (i64) from %stack.0) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -117,20 +117,20 @@ body: | ; CHECK-NEXT: BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (s64) from %stack.0) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui %stack.0, 0 :: (load (i64) from %stack.0) ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[LDRDui]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %3:gpr(p0) = G_FRAME_INDEX %stack.0 ADJCALLSTACKDOWN 0, 0, implicit-def $sp, implicit $sp - $d0 = COPY %0(s64) + $d0 = COPY %0(i64) $x0 = COPY %3(p0) BL &modf, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $d0, implicit $x0, implicit-def $d0 ADJCALLSTACKUP 0, 0, implicit-def $sp, implicit $sp - %1:fpr(s64) = COPY $d0 - %2:fpr(s64) = G_LOAD %3(p0) :: (load (s64) from %stack.0) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %1:fpr(i64) = COPY $d0 + %2:fpr(i64) = G_LOAD %3(p0) :: (load (i64) from %stack.0) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir index cf227cbb6f33b..640f225ea7d90 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir @@ -28,7 +28,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[UCVTFd:%[0-9]+]]:fpr64 = UCVTFd [[COPY]], 12 ; CHECK-NEXT: $d1 = COPY [[UCVTFd]] - %0(s64) = COPY $d0 - %2(s64) = G_INTRINSIC intrinsic(@llvm.aarch64.neon.vcvtfxu2fp.f64), %0, 12 - $d1 = COPY %2(s64) + %0(i64) = COPY $d0 + %2(f64) = G_INTRINSIC intrinsic(@llvm.aarch64.neon.vcvtfxu2fp.f64), %0, 12 + $d1 = COPY %2(f64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir index 349513158e41c..90fbb993cc677 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ptr-add.mir @@ -15,8 +15,8 @@ body: | ; CHECK-NEXT: [[ADDXri:%[0-9]+]]:gpr64sp = ADDXri [[COPY1]], 42, 0 ; CHECK-NEXT: $x0 = COPY [[ADDXri]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 42 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 42 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -35,8 +35,8 @@ body: | ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[COPY1]] ; CHECK-NEXT: $x0 = COPY [[ADDXrr]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = COPY $x1 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -56,8 +56,8 @@ body: | ; CHECK-NEXT: [[ADDXrr:%[0-9]+]]:gpr64 = ADDXrr [[COPY]], [[SUBREG_TO_REG]] ; CHECK-NEXT: $x0 = COPY [[ADDXrr]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 10000 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 10000 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... @@ -76,8 +76,8 @@ body: | ; CHECK-NEXT: [[ADDv2i64_:%[0-9]+]]:fpr128 = ADDv2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ADDv2i64_]] %0:fpr(<2 x p0>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %3:fpr(<2 x p0>) = G_PTR_ADD %0, %1(<2 x s64>) + %1:fpr(<2 x i64>) = COPY $q1 + %3:fpr(<2 x p0>) = G_PTR_ADD %0, %1(<2 x i64>) $q0 = COPY %3(<2 x p0>) ... --- @@ -95,8 +95,8 @@ body: | ; CHECK-NEXT: [[SUBSXri:%[0-9]+]]:gpr64 = SUBSXri [[COPY1]], 10, 0, implicit-def dead $nzcv ; CHECK-NEXT: $x0 = COPY [[SUBSXri]] %0:gpr(p0) = COPY $x0 - %1:gpr(s64) = G_CONSTANT i64 -10 - %2:gpr(p0) = G_PTR_ADD %0, %1(s64) + %1:gpr(i64) = G_CONSTANT i64 -10 + %2:gpr(p0) = G_PTR_ADD %0, %1(i64) $x0 = COPY %2(p0) ... --- @@ -114,12 +114,12 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY %ptr ; CHECK-NEXT: %ptr_add:gpr64sp = ADDXrx [[COPY]], %reg0, 18 ; CHECK-NEXT: $x0 = COPY %ptr_add - %reg0:gpr(s32) = COPY $w0 + %reg0:gpr(i32) = COPY $w0 %ptr:gpr(p0) = COPY $x1 - %ext:gpr(s64) = G_ZEXT %reg0(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %ptr_add:gpr(p0) = G_PTR_ADD %ptr, %shift(s64) + %ext:gpr(i64) = G_ZEXT %reg0(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %ptr_add:gpr(p0) = G_PTR_ADD %ptr, %shift(i64) $x0 = COPY %ptr_add(p0) ... --- @@ -137,9 +137,9 @@ body: | ; CHECK-NEXT: [[SUBSXrr:%[0-9]+]]:gpr64 = SUBSXrr [[COPY]], %src, implicit-def dead $nzcv ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] %0:gpr(p0) = COPY $x0 - %src:gpr(s64) = COPY $x1 - %1:gpr(s64) = G_CONSTANT i64 0 - %neg:gpr(s64) = G_SUB %1, %src - %2:gpr(p0) = G_PTR_ADD %0, %neg(s64) + %src:gpr(i64) = COPY $x1 + %1:gpr(i64) = G_CONSTANT i64 0 + %neg:gpr(i64) = G_SUB %1, %src + %2:gpr(p0) = G_PTR_ADD %0, %neg(i64) $x0 = COPY %2(p0) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir index b743cb9f7c578..e48664da8e97a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir @@ -16,14 +16,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x s8>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<16 x i8>)) ; CHECK-NEXT: [[ADDVv16i8v:%[0-9]+]]:fpr8 = ADDVv16i8v [[LDRQui]] ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[ADDVv16i8v]], %subreg.bsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x s8>)) + %1:fpr(<16 x i8>) = G_LOAD %0(p0) :: (load (<16 x i8>)) %2:fpr(i8) = G_VECREDUCE_ADD %1(<16 x i8>) %4:gpr(i8) = COPY %2(i8) %3:gpr(i32) = G_ANYEXT %4(i8) @@ -47,14 +47,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x s16>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<8 x i16>)) ; CHECK-NEXT: [[ADDVv8i16v:%[0-9]+]]:fpr16 = ADDVv8i16v [[LDRQui]] ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG [[ADDVv8i16v]], %subreg.hsub ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x s16>)) + %1:fpr(<8 x i16>) = G_LOAD %0(p0) :: (load (<8 x i16>)) %2:fpr(i16) = G_VECREDUCE_ADD %1(<8 x i16>) %4:gpr(i16) = COPY %2(i16) %3:gpr(i32) = G_ANYEXT %4(i16) @@ -78,12 +78,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x s32>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x i32>)) ; CHECK-NEXT: [[ADDVv4i32v:%[0-9]+]]:fpr32 = ADDVv4i32v [[LDRQui]] ; CHECK-NEXT: $w0 = COPY [[ADDVv4i32v]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x s32>)) + %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x i32>)) %2:fpr(i32) = G_VECREDUCE_ADD %1(<4 x i32>) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -105,13 +105,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x s32>)) + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[COPY]], 0 :: (load (<2 x i32>)) ; CHECK-NEXT: [[ADDPv2i32_:%[0-9]+]]:fpr64 = ADDPv2i32 [[LDRDui]], [[LDRDui]] ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[ADDPv2i32_]].ssub ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %1:fpr(<2 x i32>) = G_LOAD %0(p0) :: (load (<2 x s32>)) + %1:fpr(<2 x i32>) = G_LOAD %0(p0) :: (load (<2 x i32>)) %2:fpr(i32) = G_VECREDUCE_ADD %1(<2 x i32>) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -133,12 +133,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x s64>)) + ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<2 x i64>)) ; CHECK-NEXT: [[ADDPv2i64p:%[0-9]+]]:fpr64 = ADDPv2i64p [[LDRQui]] ; CHECK-NEXT: $x0 = COPY [[ADDPv2i64p]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %1:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x s64>)) + %1:fpr(<2 x i64>) = G_LOAD %0(p0) :: (load (<2 x i64>)) %2:fpr(i64) = G_VECREDUCE_ADD %1(<2 x i64>) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir index dc7c975edb488..3f7dc2a8b7349 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext-of-load.mir @@ -13,14 +13,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRBBui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(p0) = COPY $x0 - %2:gpr(s8) = G_LOAD %1(p0) :: (load (s8)) - %3:gpr(s32) = G_ZEXT %2(s8) - $w0 = COPY %3(s32) + %2:gpr(i8) = G_LOAD %1(p0) :: (load (i8)) + %3:gpr(i32) = G_ZEXT %2(i8) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... @@ -37,14 +37,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(p0) = COPY $x0 - %2:gpr(s16) = G_LOAD %1(p0) :: (load (s16)) - %3:gpr(s32) = G_ZEXT %2(s16) - $w0 = COPY %3(s32) + %2:gpr(i16) = G_LOAD %1(p0) :: (load (i16)) + %3:gpr(i32) = G_ZEXT %2(i16) + $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir index f5a94c7ad51fe..f4ce1af7f5a27 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-redundant-zext.mir @@ -52,8 +52,8 @@ body: | ; CHECK-NEXT: [[UBFMXri:%[0-9]+]]:gpr64 = UBFMXri [[SUBREG_TO_REG]], 0, 15 ; CHECK-NEXT: $x0 = COPY [[UBFMXri]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:gpr(s16) = G_IMPLICIT_DEF - %3:gpr(i64) = G_ZEXT %0(s16) + %0:gpr(i16) = G_IMPLICIT_DEF + %3:gpr(i64) = G_ZEXT %0(i16) $x0 = COPY %3(i64) RET_ReallyLR implicit $x0 @@ -104,7 +104,7 @@ body: | ; CHECK-NEXT: $x0 = COPY %zext ; CHECK-NEXT: RET_ReallyLR implicit $x0 %copy:gpr(i32) = COPY $w0 - %bitcast0:gpr(<4 x s8>) = G_BITCAST %copy(i32) + %bitcast0:gpr(<4 x i8>) = G_BITCAST %copy(i32) %bitcast1:gpr(i32) = G_BITCAST %bitcast0 %zext:gpr(i64) = G_ZEXT %bitcast1(i32) $x0 = COPY %zext(i64) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir index d011143667e48..a95d9e45a6505 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-rev.mir @@ -27,9 +27,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v2i32 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<2 x s32>) = COPY $d0 - %rev:fpr(<2 x s32>) = G_REV64 %copy - $d0 = COPY %rev(<2 x s32>) + %copy:fpr(<2 x i32>) = COPY $d0 + %rev:fpr(<2 x i32>) = G_REV64 %copy + $d0 = COPY %rev(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -49,9 +49,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v4i16 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<4 x s16>) = COPY $d0 - %rev:fpr(<4 x s16>) = G_REV64 %copy - $d0 = COPY %rev(<4 x s16>) + %copy:fpr(<4 x i16>) = COPY $d0 + %rev:fpr(<4 x i16>) = G_REV64 %copy + $d0 = COPY %rev(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -71,9 +71,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v4i32 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<4 x s32>) = COPY $q0 - %rev:fpr(<4 x s32>) = G_REV64 %copy - $q0 = COPY %rev(<4 x s32>) + %copy:fpr(<4 x i32>) = COPY $q0 + %rev:fpr(<4 x i32>) = G_REV64 %copy + $q0 = COPY %rev(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -93,9 +93,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV64v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev:fpr(<8 x s8>) = G_REV64 %copy - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev:fpr(<8 x i8>) = G_REV64 %copy + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -115,9 +115,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v8i16 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<8 x s16>) = COPY $q0 - %rev:fpr(<8 x s16>) = G_REV64 %copy - $q0 = COPY %rev(<8 x s16>) + %copy:fpr(<8 x i16>) = COPY $q0 + %rev:fpr(<8 x i16>) = G_REV64 %copy + $q0 = COPY %rev(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -137,9 +137,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV64v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev:fpr(<16 x s8>) = G_REV64 %copy - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev:fpr(<16 x i8>) = G_REV64 %copy + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -159,9 +159,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV32v4i16 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<4 x s16>) = COPY $d0 - %rev:fpr(<4 x s16>) = G_REV32 %copy - $d0 = COPY %rev(<4 x s16>) + %copy:fpr(<4 x i16>) = COPY $d0 + %rev:fpr(<4 x i16>) = G_REV32 %copy + $d0 = COPY %rev(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -181,9 +181,9 @@ body: | ; CHECK-NEXT: %rev:fpr64 = REV32v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev:fpr(<8 x s8>) = G_REV32 %copy - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev:fpr(<8 x i8>) = G_REV32 %copy + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -203,9 +203,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV32v8i16 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<8 x s16>) = COPY $q0 - %rev:fpr(<8 x s16>) = G_REV32 %copy - $q0 = COPY %rev(<8 x s16>) + %copy:fpr(<8 x i16>) = COPY $q0 + %rev:fpr(<8 x i16>) = G_REV32 %copy + $q0 = COPY %rev(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -225,9 +225,9 @@ body: | ; CHECK-NEXT: %rev:fpr128 = REV32v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev:fpr(<16 x s8>) = G_REV32 %copy - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev:fpr(<16 x i8>) = G_REV32 %copy + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -247,11 +247,11 @@ body: | ; CHECK-NEXT: %rev2:fpr64 = REV16v8i8 %copy ; CHECK-NEXT: $d0 = COPY %rev2 ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:fpr(<8 x s8>) = COPY $d0 - %rev1:fpr(<4 x s16>) = G_BITCAST %copy - %rev2:fpr(<4 x s16>) = G_BSWAP %rev1 - %rev:fpr(<8 x s8>) = G_BITCAST %rev2 - $d0 = COPY %rev(<8 x s8>) + %copy:fpr(<8 x i8>) = COPY $d0 + %rev1:fpr(<4 x i16>) = G_BITCAST %copy + %rev2:fpr(<4 x i16>) = G_BSWAP %rev1 + %rev:fpr(<8 x i8>) = G_BITCAST %rev2 + $d0 = COPY %rev(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -271,9 +271,9 @@ body: | ; CHECK-NEXT: %rev2:fpr128 = REV16v16i8 %copy ; CHECK-NEXT: $q0 = COPY %rev2 ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:fpr(<16 x s8>) = COPY $q0 - %rev1:fpr(<8 x s16>) = G_BITCAST %copy - %rev2:fpr(<8 x s16>) = G_BSWAP %rev1 - %rev:fpr(<16 x s8>) = G_BITCAST %rev2 - $q0 = COPY %rev(<16 x s8>) + %copy:fpr(<16 x i8>) = COPY $q0 + %rev1:fpr(<8 x i16>) = G_BITCAST %copy + %rev2:fpr(<8 x i16>) = G_BSWAP %rev1 + %rev:fpr(<16 x i8>) = G_BITCAST %rev2 + $q0 = COPY %rev(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir index e98ab4af57097..893236c83c57d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sadde.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_SADDE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_SADDE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_SADDE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_SADDE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_UADDO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_SADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_UADDO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_SADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_SADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_SADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: $x2 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_UADDO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_UADDO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_SADDE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_SADDE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 7, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_UADDO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_SADDE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_UADDO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_SADDE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir index fe272c68d450f..4bf7128418ae6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-saddo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADDSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_SADDO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_SADDO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_SADDO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_SADDO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_SADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_SADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = ADDSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_SADDO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_SADDO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir index bbf6239b510cf..22cf6b4bab615 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sbfx.mir @@ -17,10 +17,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr32 = SBFMWri %copy, 0, 9 ; CHECK-NEXT: $w0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 0 - %cst2:gpr(s32) = G_CONSTANT i32 10 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 0 + %cst2:gpr(i32) = G_CONSTANT i32 10 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 @@ -40,10 +40,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr64 = SBFMXri %copy, 0, 9 ; CHECK-NEXT: $x0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 0 - %cst2:gpr(s64) = G_CONSTANT i64 10 - %sbfx:gpr(s64) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 0 + %cst2:gpr(i64) = G_CONSTANT i64 10 + %sbfx:gpr(i64) = G_SBFX %copy, %cst1, %cst2 $x0 = COPY %sbfx RET_ReallyLR implicit $x0 @@ -65,10 +65,10 @@ body: | ; CHECK-NEXT: %sbfx:gpr32 = SBFMWri %copy, 31, 31 ; CHECK-NEXT: $w0 = COPY %sbfx ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 1 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 31 + %cst2:gpr(i32) = G_CONSTANT i32 1 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 --- @@ -85,10 +85,10 @@ body: | ; CHECK: %sbfx:gpr32 = SBFMWri %copy, 10, 14 ; CHECK: $w0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 10 - %cst2:gpr(s32) = G_CONSTANT i32 5 - %sbfx:gpr(s32) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 10 + %cst2:gpr(i32) = G_CONSTANT i32 5 + %sbfx:gpr(i32) = G_SBFX %copy, %cst1, %cst2 $w0 = COPY %sbfx RET_ReallyLR implicit $w0 --- @@ -105,9 +105,9 @@ body: | ; CHECK: %sbfx:gpr64 = SBFMXri %copy, 10, 14 ; CHECK: $x0 = COPY %sbfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 10 - %cst2:gpr(s64) = G_CONSTANT i64 5 - %sbfx:gpr(s64) = G_SBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 10 + %cst2:gpr(i64) = G_CONSTANT i64 5 + %sbfx:gpr(i64) = G_SBFX %copy, %cst1, %cst2 $x0 = COPY %sbfx RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir index 42b1c61949b94..85e5b1bb9e957 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-scalar-merge.mir @@ -29,8 +29,8 @@ body: | ; CHECK-NEXT: [[SUBREG_TO_REG1:%[0-9]+]]:gpr64 = SUBREG_TO_REG [[COPY1]], %subreg.sub_32 ; CHECK-NEXT: [[BFMXri:%[0-9]+]]:gpr64 = BFMXri [[SUBREG_TO_REG]], [[SUBREG_TO_REG1]], 32, 31 ; CHECK-NEXT: $x0 = COPY [[BFMXri]] - %0(s32) = COPY $w0 - %1(s32) = COPY $w1 - %2(s64) = G_MERGE_VALUES %0(s32), %1(s32) - $x0 = COPY %2(s64) + %0(i32) = COPY $w0 + %1(i32) = COPY $w1 + %2(i64) = G_MERGE_VALUES %0(i32), %1(i32) + $x0 = COPY %2(i64) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir index d2bf5839f1be7..6aca3c31774aa 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-sextload.mir @@ -21,10 +21,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRSHWui:%[0-9]+]]:gpr32 = LDRSHWui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRSHWui:%[0-9]+]]:gpr32 = LDRSHWui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: $w0 = COPY [[LDRSHWui]] %0:gpr(p0) = COPY $x0 - %1:gpr(i32) = G_SEXTLOAD %0 :: (load (s16) from %ir.addr) + %1:gpr(i32) = G_SEXTLOAD %0 :: (load (i16) from %ir.addr) $w0 = COPY %1(i32) ... @@ -41,11 +41,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16) from %ir.addr) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16) from %ir.addr) ; CHECK-NEXT: [[SBFMWri:%[0-9]+]]:gpr32 = SBFMWri [[LDRHHui]], 0, 15 ; CHECK-NEXT: $w0 = COPY [[SBFMWri]] %0:gpr(p0) = COPY $x0 - %1:gpr(i16) = G_LOAD %0 :: (load (s16) from %ir.addr) + %1:gpr(i16) = G_LOAD %0 :: (load (i16) from %ir.addr) %2:gpr(i32) = G_SEXT %1 $w0 = COPY %2(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir index 345cc774f9963..666e7c059a8e1 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir @@ -59,10 +59,10 @@ body: | ; CHECK: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub ; CHECK: $d0 = COPY [[COPY2]] ; CHECK: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0) - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 0) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -90,10 +90,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 3, 0) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 1, 3, 0) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -121,10 +121,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(5, 7, 1, 0) - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(5, 7, 1, 0) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -152,10 +152,10 @@ body: | ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]] ; CHECK: $q0 = COPY [[TBLv16i8Two]] ; CHECK: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 0) - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 0) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir index a5ac0b7ff8626..86350664abf63 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-shufflevec-undef-mask-elt.mir @@ -36,12 +36,12 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %6:gpr(s32) = G_IMPLICIT_DEF - %7:gpr(s32) = G_IMPLICIT_DEF - %2:fpr(<2 x s32>) = G_BUILD_VECTOR %6(s32), %7(s32) - %1:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - $d0 = COPY %1(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %6:gpr(i32) = G_IMPLICIT_DEF + %7:gpr(i32) = G_IMPLICIT_DEF + %2:fpr(<2 x i32>) = G_BUILD_VECTOR %6(i32), %7(i32) + %1:fpr(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %2, shufflemask(1, undef) + $d0 = COPY %1(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir index a9da51781efbe..1b3ae63e0c9c4 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssube.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_SSUBE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_SSUBE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SBCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_SSUBE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_SSUBE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_USUBO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_USUBO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: $x2 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_USUBO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_USUBO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_SSUBE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_SSUBE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 7, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_USUBO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_SSUBE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_USUBO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_SSUBE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir index 700a7e298ec5f..c2b116b3f77ea 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ssubo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SUBSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_SSUBO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_SSUBO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_SSUBO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_SSUBO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_SSUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_SSUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = SUBSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_SSUBO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_SSUBO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir index 3503b8e13c588..1dd0e8f1288e5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-st2.mir @@ -18,12 +18,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov8b [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov8b [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<8 x s8>) = COPY $d0 - %src2:fpr(<8 x s8>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x s8>), %src2(<8 x s8>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<8 x i8>) = COPY $d0 + %src2:fpr(<8 x i8>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x i8>), %src2(<8 x i8>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -44,12 +44,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov16b [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov16b [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<16 x s8>) = COPY $q0 - %src2:fpr(<16 x s8>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<16 x s8>), %src2(<16 x s8>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<16 x i8>) = COPY $q0 + %src2:fpr(<16 x i8>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<16 x i8>), %src2(<16 x i8>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -70,12 +70,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov4h [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov4h [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<4 x s16>) = COPY $d0 - %src2:fpr(<4 x s16>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x s16>), %src2(<4 x s16>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<4 x i16>) = COPY $d0 + %src2:fpr(<4 x i16>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x i16>), %src2(<4 x i16>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -96,12 +96,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov8h [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov8h [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<8 x s16>) = COPY $q0 - %src2:fpr(<8 x s16>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x s16>), %src2(<8 x s16>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<8 x i16>) = COPY $q0 + %src2:fpr(<8 x i16>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<8 x i16>), %src2(<8 x i16>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -121,12 +121,12 @@ body: | ; CHECK-NEXT: %src1:fpr64 = COPY $d0 ; CHECK-NEXT: %src2:fpr64 = COPY $d1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST2Twov2s [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST2Twov2s [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<2 x s32>) = COPY $d0 - %src2:fpr(<2 x s32>) = COPY $d1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x s32>), %src2(<2 x s32>), %ptr(p0) :: (store (<2 x s64>)) + %src1:fpr(<2 x i32>) = COPY $d0 + %src2:fpr(<2 x i32>) = COPY $d1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x i32>), %src2(<2 x i32>), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -146,12 +146,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov4s [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov4s [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<4 x s32>) = COPY $q0 - %src2:fpr(<4 x s32>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x s32>), %src2(<4 x s32>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<4 x i32>) = COPY $q0 + %src2:fpr(<4 x i32>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<4 x i32>), %src2(<4 x i32>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -171,12 +171,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:fpr(<2 x s64>) = COPY $q0 - %src2:fpr(<2 x s64>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x s64>), %src2(<2 x s64>), %ptr(p0) :: (store (<4 x s64>)) + %src1:fpr(<2 x i64>) = COPY $q0 + %src2:fpr(<2 x i64>) = COPY $q1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x i64>), %src2(<2 x i64>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -196,12 +196,12 @@ body: | ; CHECK-NEXT: %src1:fpr128 = COPY $q0 ; CHECK-NEXT: %src2:fpr128 = COPY $q1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE %src1, %subreg.qsub0, %src2, %subreg.qsub1 - ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x s64>)) + ; CHECK-NEXT: ST2Twov2d [[REG_SEQUENCE]], %ptr :: (store (<4 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 %src1:fpr(<2 x p0>) = COPY $q0 %src2:fpr(<2 x p0>) = COPY $q1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x p0>), %src2(<2 x p0>), %ptr(p0) :: (store (<4 x s64>)) + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(<2 x p0>), %src2(<2 x p0>), %ptr(p0) :: (store (<4 x i64>)) RET_ReallyLR ... @@ -221,12 +221,12 @@ body: | ; CHECK-NEXT: %src1:gpr64all = COPY $x0 ; CHECK-NEXT: %src2:gpr64all = COPY $x1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 - %src1:gpr(s64) = COPY $x0 - %src2:gpr(s64) = COPY $x1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(s64), %src2(s64), %ptr(p0) :: (store (<2 x s64>)) + %src1:gpr(i64) = COPY $x0 + %src2:gpr(i64) = COPY $x1 + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(i64), %src2(i64), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -246,12 +246,12 @@ body: | ; CHECK-NEXT: %src1:gpr64all = COPY $x0 ; CHECK-NEXT: %src2:gpr64all = COPY $x1 ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:dd = REG_SEQUENCE %src1, %subreg.dsub0, %src2, %subreg.dsub1 - ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x s64>)) + ; CHECK-NEXT: ST1Twov1d [[REG_SEQUENCE]], %ptr :: (store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %ptr:gpr(p0) = COPY $x0 %src1:gpr(p0) = COPY $x0 %src2:gpr(p0) = COPY $x1 - G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(p0), %src2(p0), %ptr(p0) :: (store (<2 x s64>)) + G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), %src1(p0), %src2(p0), %ptr(p0) :: (store (<2 x i64>)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir index df13c02374fed..10150a882e9de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-static.mir @@ -60,7 +60,7 @@ body: | bb.0: liveins: $x0 %0:gpr(p0) = COPY $x0 - %const:gpr(s64) = G_CONSTANT i64 -8 + %const:gpr(i64) = G_CONSTANT i64 -8 %1:gpr(p0) = G_PTRMASK %0, %const $x0 = COPY %1(p0) ... @@ -139,16 +139,16 @@ body: | bb.0: liveins: $w0, $x0 - %0(s32) = COPY $w0 - %1(s32) = G_ICMP intpred(eq), %0, %0 + %0(i32) = COPY $w0 + %1(i32) = G_ICMP intpred(eq), %0, %0 $w0 = COPY %1 - %2(s64) = COPY $x0 - %3(s32) = G_ICMP intpred(uge), %2, %2 + %2(i64) = COPY $x0 + %3(i32) = G_ICMP intpred(uge), %2, %2 $w0 = COPY %3 %4(p0) = COPY $x0 - %5(s32) = G_ICMP intpred(ne), %4, %4 + %5(i32) = G_ICMP intpred(ne), %4, %4 $w0 = COPY %5 ... @@ -184,12 +184,12 @@ body: | bb.0: liveins: $w0, $x0 - %0(s32) = COPY $s0 - %1(s32) = G_FCMP floatpred(one), %0, %0 + %0(f32) = COPY $s0 + %1(i32) = G_FCMP floatpred(one), %0, %0 $w0 = COPY %1 - %2(s64) = COPY $d0 - %3(s32) = G_FCMP floatpred(uge), %2, %2 + %2(f64) = COPY $d0 + %3(i32) = G_FCMP floatpred(uge), %2, %2 $w0 = COPY %3 ... @@ -219,12 +219,12 @@ body: | bb.0: liveins: $s0, $w0 successors: %bb.1 - %0(s32) = COPY $s0 - %3:gpr(s32) = COPY $w0 + %0(i32) = COPY $s0 + %3:gpr(i32) = COPY $w0 bb.1: successors: %bb.1, %bb.2 - %2(s32) = PHI %0, %bb.0, %2, %bb.1 + %2(i32) = PHI %0, %bb.0, %2, %bb.1 G_BRCOND %3, %bb.1 bb.2: @@ -272,17 +272,17 @@ registers: body: | bb.0: liveins: $w0, $w1, $w2 - %0:gpr(s32) = COPY $w0 + %0:gpr(i32) = COPY $w0 - %1(s32) = COPY $w1 - %2(s32) = COPY $w2 - %3(s32) = G_SELECT %0, %1, %2 - $w0 = COPY %3(s32) + %1(i32) = COPY $w1 + %2(i32) = COPY $w2 + %3(i32) = G_SELECT %0, %1, %2 + $w0 = COPY %3(i32) - %4(s64) = COPY $x0 - %5(s64) = COPY $x1 - %6(s64) = G_SELECT %0, %4, %5 - $x0 = COPY %6(s64) + %4(i64) = COPY $x0 + %5(i64) = COPY $x1 + %6(i64) = G_SELECT %0, %4, %5 + $x0 = COPY %6(i64) %7(p0) = COPY $x0 %8(p0) = COPY $x1 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir index 857ed9b3efbd3..f75aa7766131c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-stlxr-intrin.mir @@ -28,12 +28,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %2:gpr32 = STLXRX [[COPY]], [[COPY1]] :: (volatile store (s64) into %ir.addr) + ; CHECK-NEXT: early-clobber %2:gpr32 = STLXRX [[COPY]], [[COPY1]] :: (volatile store (i64) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i64) = COPY $x1 %2:gpr(p0) = COPY $x2 - %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %1(i64), %2(p0) :: (volatile store (s64) into %ir.addr) + %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %1(i64), %2(p0) :: (volatile store (i64) into %ir.addr) $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 @@ -52,13 +52,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %3:gpr32 = STLXRW [[COPY]], [[COPY1]] :: (volatile store (s32) into %ir.addr) + ; CHECK-NEXT: early-clobber %3:gpr32 = STLXRW [[COPY]], [[COPY1]] :: (volatile store (i32) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 %3:gpr(i64) = G_ZEXT %1(i32) - %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %3(i64), %2(p0) :: (volatile store (s32) into %ir.addr) + %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %3(i64), %2(p0) :: (volatile store (i32) into %ir.addr) $w0 = COPY %4(i32) RET_ReallyLR implicit $w0 @@ -81,7 +81,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRB [[COPY2]], [[COPY1]] :: (volatile store (s8) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRB [[COPY2]], [[COPY1]] :: (volatile store (i8) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -89,7 +89,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 255 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (s8) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (i8) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -112,7 +112,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRH [[COPY2]], [[COPY1]] :: (volatile store (s16) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STLXRH [[COPY2]], [[COPY1]] :: (volatile store (i16) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -120,6 +120,6 @@ body: | %6:gpr(i64) = G_CONSTANT i64 65535 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (s16) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stlxr), %4(i64), %2(p0) :: (volatile store (i16) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir index 5953e5773bfa3..267157d04fa1f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-store-truncating-float.mir @@ -48,11 +48,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub - ; CHECK-NEXT: STRSui [[COPY1]], %stack.0.alloca, 0 :: (store (s32) into %ir.alloca) + ; CHECK-NEXT: STRSui [[COPY1]], %stack.0.alloca, 0 :: (store (i32) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s32) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i32) into %ir.alloca) RET_ReallyLR ... @@ -78,11 +78,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr16 = COPY [[COPY]].hsub - ; CHECK-NEXT: STRHui [[COPY1]], %stack.0.alloca, 0 :: (store (s16) into %ir.alloca) + ; CHECK-NEXT: STRHui [[COPY1]], %stack.0.alloca, 0 :: (store (i16) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s16) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i16) into %ir.alloca) RET_ReallyLR ... @@ -108,11 +108,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr8 = COPY [[COPY]].bsub - ; CHECK-NEXT: STRBui [[COPY1]], %stack.0.alloca, 0 :: (store (s8) into %ir.alloca) + ; CHECK-NEXT: STRBui [[COPY1]], %stack.0.alloca, 0 :: (store (i8) into %ir.alloca) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(s64) = COPY $d0 + %0:fpr(i64) = COPY $d0 %1:gpr(p0) = G_FRAME_INDEX %stack.0.alloca - G_STORE %0(s64), %1(p0) :: (store (s8) into %ir.alloca) + G_STORE %0(i64), %1(p0) :: (store (i8) into %ir.alloca) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir index ade4322f5d87e..3cc6ef4d4cb0b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-store.mir @@ -65,10 +65,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $x1 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = COPY $x1 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -90,10 +90,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $w1 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = COPY $w1 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -115,11 +115,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (s16) into %ir.addr) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (i16) into %ir.addr) %0(p0) = COPY $x0 - %2:gpr(s32) = COPY $w1 - %1(s16) = G_TRUNC %2 - G_STORE %1, %0 :: (store (s16) into %ir.addr) + %2:gpr(i32) = COPY $w1 + %1(i16) = G_TRUNC %2 + G_STORE %1, %0 :: (store (i16) into %ir.addr) ... @@ -141,11 +141,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 0 :: (store (s8) into %ir.addr) + ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 0 :: (store (i8) into %ir.addr) %0(p0) = COPY $x0 - %2:gpr(s32) = COPY $w1 - %1(s8) = G_TRUNC %2 - G_STORE %1, %0 :: (store (s8) into %ir.addr) + %2:gpr(i32) = COPY $w1 + %1(i8) = G_TRUNC %2 + G_STORE %1, %0 :: (store (i8) into %ir.addr) ... @@ -166,10 +166,10 @@ body: | ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = G_CONSTANT i64 0 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = G_CONSTANT i64 0 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -190,10 +190,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRWui $wzr, [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui $wzr, [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = G_CONSTANT i32 0 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = G_CONSTANT i32 0 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -208,10 +208,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRHHui $wzr, [[COPY]], 0 :: (store (s16)) + ; CHECK-NEXT: STRHHui $wzr, [[COPY]], 0 :: (store (i16)) %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_CONSTANT i16 0 - G_STORE %1(s16), %0(p0) :: (store (s16)) + %1:gpr(i16) = G_CONSTANT i16 0 + G_STORE %1(i16), %0(p0) :: (store (i16)) ... @@ -226,10 +226,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRBBui $wzr, [[COPY]], 0 :: (store (s8)) + ; CHECK-NEXT: STRBBui $wzr, [[COPY]], 0 :: (store (i8)) %0:gpr(p0) = COPY $x0 - %1:gpr(s8) = G_CONSTANT i8 0 - G_STORE %1(s8), %0(p0) :: (store (s8)) + %1:gpr(i8) = G_CONSTANT i8 0 + G_STORE %1(i8), %0(p0) :: (store (i8)) ... --- @@ -243,11 +243,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui $xzr, [[COPY]], 0 :: (store (i64) into %ir.addr) %0:gpr(p0) = COPY $x0 - %1:gpr(s32) = G_CONSTANT i32 0 - %2:gpr(s64) = G_ZEXT %1 - G_STORE %2, %0 :: (store (s64) into %ir.addr) + %1:gpr(i32) = G_CONSTANT i32 0 + %2:gpr(i64) = G_ZEXT %1 + G_STORE %2, %0 :: (store (i64) into %ir.addr) ... --- @@ -297,12 +297,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64 = COPY $x1 - ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 16 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRXui [[COPY1]], [[COPY]], 16 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $x1 - %2(s64) = G_CONSTANT i64 128 + %1(i64) = COPY $x1 + %2(i64) = G_CONSTANT i64 128 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s64) into %ir.addr) + G_STORE %1, %3 :: (store (i64) into %ir.addr) ... --- @@ -325,12 +325,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 128 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRWui [[COPY1]], [[COPY]], 128 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $w1 - %2(s64) = G_CONSTANT i64 512 + %1(i32) = COPY $w1 + %2(i64) = G_CONSTANT i64 512 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s32) into %ir.addr) + G_STORE %1, %3 :: (store (i32) into %ir.addr) ... --- @@ -353,13 +353,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 32 :: (store (s16) into %ir.addr) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 32 :: (store (i16) into %ir.addr) %0(p0) = COPY $x0 - %4:gpr(s32) = COPY $w1 - %1(s16) = G_TRUNC %4 - %2(s64) = G_CONSTANT i64 64 + %4:gpr(i32) = COPY $w1 + %1(i16) = G_TRUNC %4 + %2(i64) = G_CONSTANT i64 64 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s16) into %ir.addr) + G_STORE %1, %3 :: (store (i16) into %ir.addr) ... --- @@ -382,13 +382,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 1 :: (store (s8) into %ir.addr) + ; CHECK-NEXT: STRBBui [[COPY1]], [[COPY]], 1 :: (store (i8) into %ir.addr) %0(p0) = COPY $x0 - %4:gpr(s32) = COPY $w1 - %1(s8) = G_TRUNC %4 - %2(s64) = G_CONSTANT i64 1 + %4:gpr(i32) = COPY $w1 + %1(i8) = G_TRUNC %4 + %2(i64) = G_CONSTANT i64 1 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s8) into %ir.addr) + G_STORE %1, %3 :: (store (i8) into %ir.addr) ... --- @@ -409,10 +409,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $d1 - G_STORE %1, %0 :: (store (s64) into %ir.addr) + %1(i64) = COPY $d1 + G_STORE %1, %0 :: (store (i64) into %ir.addr) ... @@ -434,10 +434,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $s1 - ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 0 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 0 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $s1 - G_STORE %1, %0 :: (store (s32) into %ir.addr) + %1(i32) = COPY $s1 + G_STORE %1, %0 :: (store (i32) into %ir.addr) ... @@ -461,12 +461,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 1 :: (store (s64) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 1 :: (store (i64) into %ir.addr) %0(p0) = COPY $x0 - %1(s64) = COPY $d1 - %2(s64) = G_CONSTANT i64 8 + %1(i64) = COPY $d1 + %2(i64) = G_CONSTANT i64 8 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s64) into %ir.addr) + G_STORE %1, %3 :: (store (i64) into %ir.addr) ... --- @@ -489,12 +489,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY $s1 - ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 2 :: (store (s32) into %ir.addr) + ; CHECK-NEXT: STRSui [[COPY1]], [[COPY]], 2 :: (store (i32) into %ir.addr) %0(p0) = COPY $x0 - %1(s32) = COPY $s1 - %2(s64) = G_CONSTANT i64 8 + %1(i32) = COPY $s1 + %2(i64) = G_CONSTANT i64 8 %3(p0) = G_PTR_ADD %0, %2 - G_STORE %1, %3 :: (store (s32) into %ir.addr) + G_STORE %1, %3 :: (store (i32) into %ir.addr) ... --- name: store_v2s32 @@ -514,10 +514,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1 - ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (<2 x s32>) into %ir.addr) + ; CHECK-NEXT: STRDui [[COPY1]], [[COPY]], 0 :: (store (<2 x i32>) into %ir.addr) %0(p0) = COPY $x0 - %1(<2 x s32>) = COPY $d1 - G_STORE %1, %0 :: (store (<2 x s32>) into %ir.addr) + %1(<2 x i32>) = COPY $d1 + G_STORE %1, %0 :: (store (<2 x i32>) into %ir.addr) ... --- @@ -537,10 +537,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1 - ; CHECK-NEXT: STRQui [[COPY1]], [[COPY]], 0 :: (store (<2 x s64>) into %ir.addr, align 8) + ; CHECK-NEXT: STRQui [[COPY1]], [[COPY]], 0 :: (store (<2 x i64>) into %ir.addr, align 8) %0(p0) = COPY $x0 - %1(<2 x s64>) = COPY $q1 - G_STORE %1, %0 :: (store (<2 x s64>) into %ir.addr, align 8) + %1(<2 x i64>) = COPY $q1 + G_STORE %1, %0 :: (store (<2 x i64>) into %ir.addr, align 8) ... --- @@ -562,11 +562,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRDui [[COPY]], [[COPY1]], 0 :: (store (<4 x s16>) into %ir.ptr) + ; CHECK-NEXT: STRDui [[COPY]], [[COPY1]], 0 :: (store (<4 x i16>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<4 x s16>) = COPY $d0 + %0:fpr(<4 x i16>) = COPY $d0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<4 x s16>), %1(p0) :: (store (<4 x s16>) into %ir.ptr) + G_STORE %0(<4 x i16>), %1(p0) :: (store (<4 x i16>) into %ir.ptr) RET_ReallyLR ... @@ -589,11 +589,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<4 x s32>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<4 x i32>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<4 x s32>), %1(p0) :: (store (<4 x s32>) into %ir.ptr) + G_STORE %0(<4 x i32>), %1(p0) :: (store (<4 x i32>) into %ir.ptr) RET_ReallyLR ... @@ -616,11 +616,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<8 x s16>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<8 x i16>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<8 x s16>) = COPY $q0 + %0:fpr(<8 x i16>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<8 x s16>), %1(p0) :: (store (<8 x s16>) into %ir.ptr) + G_STORE %0(<8 x i16>), %1(p0) :: (store (<8 x i16>) into %ir.ptr) RET_ReallyLR ... @@ -643,11 +643,11 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<16 x s8>) into %ir.ptr) + ; CHECK-NEXT: STRQui [[COPY]], [[COPY1]], 0 :: (store (<16 x i8>) into %ir.ptr) ; CHECK-NEXT: RET_ReallyLR - %0:fpr(<16 x s8>) = COPY $q0 + %0:fpr(<16 x i8>) = COPY $q0 %1:gpr(p0) = COPY $x0 - G_STORE %0(<16 x s8>), %1(p0) :: (store (<16 x s8>) into %ir.ptr) + G_STORE %0(<16 x i8>), %1(p0) :: (store (<16 x i8>) into %ir.ptr) RET_ReallyLR ... @@ -728,36 +728,36 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 ; CHECK-NEXT: %val32:gpr32 = COPY $w1 ; CHECK-NEXT: %val64:gpr64 = COPY $x2 - ; CHECK-NEXT: STRBBui %val32, [[COPY]], 0 :: (store (s8)) - ; CHECK-NEXT: STRBBui %val32, [[COPY]], 43 :: (store (s8)) - ; CHECK-NEXT: STRHHui %val32, [[COPY]], 0 :: (store (s16)) - ; CHECK-NEXT: STURHHi %val32, [[COPY]], 43 :: (store (s16)) + ; CHECK-NEXT: STRBBui %val32, [[COPY]], 0 :: (store (i8)) + ; CHECK-NEXT: STRBBui %val32, [[COPY]], 43 :: (store (i8)) + ; CHECK-NEXT: STRHHui %val32, [[COPY]], 0 :: (store (i16)) + ; CHECK-NEXT: STURHHi %val32, [[COPY]], 43 :: (store (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (s16)) + ; CHECK-NEXT: STRHHui [[COPY1]], [[COPY]], 0 :: (store (i16)) ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STURHHi [[COPY2]], [[COPY]], 43 :: (store (s16)) + ; CHECK-NEXT: STURHHi [[COPY2]], [[COPY]], 43 :: (store (i16)) ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STRWui [[COPY3]], [[COPY]], 0 :: (store (s32)) + ; CHECK-NEXT: STRWui [[COPY3]], [[COPY]], 0 :: (store (i32)) ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr32 = COPY %val64.sub_32 - ; CHECK-NEXT: STURWi [[COPY4]], [[COPY]], 43 :: (store (s32)) + ; CHECK-NEXT: STURWi [[COPY4]], [[COPY]], 43 :: (store (i32)) %0:gpr(p0) = COPY $x0 - %val32:gpr(s32) = COPY $w1 - %val64:gpr(s64) = COPY $x2 - G_STORE %val32, %0 :: (store (s8)) + %val32:gpr(i32) = COPY $w1 + %val64:gpr(i64) = COPY $x2 + G_STORE %val32, %0 :: (store (i8)) ; unscaled offset: - %cst:gpr(s64) = G_CONSTANT i64 43 + %cst:gpr(i64) = G_CONSTANT i64 43 %newptr:gpr(p0) = G_PTR_ADD %0, %cst - G_STORE %val32, %newptr :: (store (s8)) + G_STORE %val32, %newptr :: (store (i8)) - G_STORE %val32, %0 :: (store (s16)) + G_STORE %val32, %0 :: (store (i16)) ; unscaled offset: - G_STORE %val32, %newptr :: (store (s16)) + G_STORE %val32, %newptr :: (store (i16)) - G_STORE %val64, %0 :: (store (s16)) + G_STORE %val64, %0 :: (store (i16)) ; unscaled offset: - G_STORE %val64, %newptr :: (store (s16)) + G_STORE %val64, %newptr :: (store (i16)) - G_STORE %val64, %0 :: (store (s32)) + G_STORE %val64, %0 :: (store (i32)) ; unscaled offset: - G_STORE %val64, %newptr :: (store (s32)) + G_STORE %val64, %newptr :: (store (i32)) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir index 3cc916e020095..f293c72b763d8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-stx.mir @@ -26,7 +26,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STXRB [[COPY2]], [[COPY1]] :: (volatile store (s8) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STXRB [[COPY2]], [[COPY1]] :: (volatile store (i8) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -34,7 +34,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 255 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (s8) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (i8) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -58,7 +58,7 @@ body: | ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:gpr64 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[INSERT_SUBREG]].sub_32 - ; CHECK-NEXT: early-clobber %5:gpr32 = STXRH [[COPY2]], [[COPY1]] :: (volatile store (s16) into %ir.addr) + ; CHECK-NEXT: early-clobber %5:gpr32 = STXRH [[COPY2]], [[COPY1]] :: (volatile store (i16) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %5 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %3:gpr(i32) = COPY $w1 @@ -66,7 +66,7 @@ body: | %6:gpr(i64) = G_CONSTANT i64 65535 %7:gpr(i64) = G_ANYEXT %3(i32) %4:gpr(i64) = G_AND %7, %6 - %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (s16) into %ir.addr) + %5:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %4(i64), %2(p0) :: (volatile store (i16) into %ir.addr) $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 @@ -87,13 +87,13 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %3:gpr32 = STXRW [[COPY]], [[COPY1]] :: (volatile store (s32) into %ir.addr) + ; CHECK-NEXT: early-clobber %3:gpr32 = STXRW [[COPY]], [[COPY1]] :: (volatile store (i32) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i32) = COPY $w1 %2:gpr(p0) = COPY $x2 %3:gpr(i64) = G_ZEXT %1(i32) - %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %3(i64), %2(p0) :: (volatile store (s32) into %ir.addr) + %4:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %3(i64), %2(p0) :: (volatile store (i32) into %ir.addr) $w0 = COPY %4(i32) RET_ReallyLR implicit $w0 @@ -114,12 +114,12 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY $x1 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY $x2 - ; CHECK-NEXT: early-clobber %2:gpr32 = STXRX [[COPY]], [[COPY1]] :: (volatile store (s64) into %ir.addr) + ; CHECK-NEXT: early-clobber %2:gpr32 = STXRX [[COPY]], [[COPY1]] :: (volatile store (i64) into %ir.addr) ; CHECK-NEXT: $w0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:gpr(i64) = COPY $x1 %2:gpr(p0) = COPY $x2 - %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %1(i64), %2(p0) :: (volatile store (s64) into %ir.addr) + %3:gpr(i32) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.stxr), %1(i64), %2(p0) :: (volatile store (i64) into %ir.addr) $w0 = COPY %3(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir index 67262c27e2059..c13d607a4bcdd 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-tbnz-from-cmp.mir @@ -27,9 +27,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s64), %zero + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -56,9 +56,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %zero:gpr(s32) = G_CONSTANT i32 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s32), %zero + %copy:gpr(i32) = COPY $w0 + %zero:gpr(i32) = G_CONSTANT i32 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i32), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -85,9 +85,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(sge), %copy(s64), %zero + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(sge), %copy(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -114,9 +114,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %zero:gpr(s32) = G_CONSTANT i32 0 - %cmp:gpr(s32) = G_ICMP intpred(sge), %copy(s32), %zero + %copy:gpr(i32) = COPY $w0 + %zero:gpr(i32) = G_CONSTANT i32 0 + %cmp:gpr(i32) = G_ICMP intpred(sge), %copy(i32), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -144,9 +144,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s32) = COPY $w0 - %one:gpr(s32) = G_CONSTANT i32 1 - %cmp:gpr(s32) = G_ICMP intpred(slt), %copy(s32), %one + %copy:gpr(i32) = COPY $w0 + %one:gpr(i32) = G_CONSTANT i32 1 + %cmp:gpr(i32) = G_ICMP intpred(slt), %copy(i32), %one G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -174,12 +174,12 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %bit:gpr(s64) = G_CONSTANT i64 8 - %zero:gpr(s64) = G_CONSTANT i64 0 - %c:gpr(s64) = G_CONSTANT i64 8 - %and:gpr(s64) = G_AND %copy, %bit - %cmp:gpr(s32) = G_ICMP intpred(slt), %and(s64), %zero + %copy:gpr(i64) = COPY $x0 + %bit:gpr(i64) = G_CONSTANT i64 8 + %zero:gpr(i64) = G_CONSTANT i64 0 + %c:gpr(i64) = G_CONSTANT i64 8 + %and:gpr(i64) = G_AND %copy, %bit + %cmp:gpr(i32) = G_ICMP intpred(slt), %and(i64), %zero G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: @@ -208,9 +208,9 @@ body: | bb.0: successors: %bb.0, %bb.1 liveins: $x0 - %copy:gpr(s64) = COPY $x0 - %zero:gpr(s64) = G_CONSTANT i64 0 - %cmp:gpr(s32) = G_ICMP intpred(slt), %zero, %copy(s64) + %copy:gpr(i64) = COPY $x0 + %zero:gpr(i64) = G_CONSTANT i64 0 + %cmp:gpr(i32) = G_ICMP intpred(slt), %zero, %copy(i64) G_BRCOND %cmp, %bb.1 G_BR %bb.0 bb.1: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir index 816eaf53e0d89..44395c0da7804 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-trn.mir @@ -23,10 +23,10 @@ body: | ; CHECK-NEXT: [[TRN1v2i32_:%[0-9]+]]:fpr64 = TRN1v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_TRN1 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_TRN1 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -47,10 +47,10 @@ body: | ; CHECK-NEXT: [[TRN1v2i64_:%[0-9]+]]:fpr128 = TRN1v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_TRN1 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_TRN1 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -71,10 +71,10 @@ body: | ; CHECK-NEXT: [[TRN1v4i16_:%[0-9]+]]:fpr64 = TRN1v4i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v4i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<4 x s16>) = G_TRN1 %0, %1 - $d0 = COPY %2(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<4 x i16>) = G_TRN1 %0, %1 + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -95,10 +95,10 @@ body: | ; CHECK-NEXT: [[TRN1v4i32_:%[0-9]+]]:fpr128 = TRN1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_TRN1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_TRN1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -119,10 +119,10 @@ body: | ; CHECK-NEXT: [[TRN1v8i8_:%[0-9]+]]:fpr64 = TRN1v8i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN1v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %1:fpr(<8 x s8>) = COPY $d1 - %2:fpr(<8 x s8>) = G_TRN1 %0, %1 - $d0 = COPY %2(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %1:fpr(<8 x i8>) = COPY $d1 + %2:fpr(<8 x i8>) = G_TRN1 %0, %1 + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -143,10 +143,10 @@ body: | ; CHECK-NEXT: [[TRN1v8i16_:%[0-9]+]]:fpr128 = TRN1v8i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v8i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = COPY $q1 - %2:fpr(<8 x s16>) = G_TRN1 %0, %1 - $q0 = COPY %2(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = COPY $q1 + %2:fpr(<8 x i16>) = G_TRN1 %0, %1 + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -167,10 +167,10 @@ body: | ; CHECK-NEXT: [[TRN1v16i8_:%[0-9]+]]:fpr128 = TRN1v16i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN1v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_TRN1 %0, %1 - $q0 = COPY %2(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_TRN1 %0, %1 + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -191,10 +191,10 @@ body: | ; CHECK-NEXT: [[TRN2v2i32_:%[0-9]+]]:fpr64 = TRN2v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_TRN2 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_TRN2 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -215,10 +215,10 @@ body: | ; CHECK-NEXT: [[TRN2v2i64_:%[0-9]+]]:fpr128 = TRN2v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_TRN2 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_TRN2 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -239,10 +239,10 @@ body: | ; CHECK-NEXT: [[TRN2v4i16_:%[0-9]+]]:fpr64 = TRN2v4i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v4i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<4 x s16>) = COPY $d1 - %2:fpr(<4 x s16>) = G_TRN2 %0, %1 - $d0 = COPY %2(<4 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<4 x i16>) = COPY $d1 + %2:fpr(<4 x i16>) = G_TRN2 %0, %1 + $d0 = COPY %2(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -263,10 +263,10 @@ body: | ; CHECK-NEXT: [[TRN2v4i32_:%[0-9]+]]:fpr128 = TRN2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_TRN2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_TRN2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -287,10 +287,10 @@ body: | ; CHECK-NEXT: [[TRN2v8i8_:%[0-9]+]]:fpr64 = TRN2v8i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[TRN2v8i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %1:fpr(<8 x s8>) = COPY $d1 - %2:fpr(<8 x s8>) = G_TRN2 %0, %1 - $d0 = COPY %2(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %1:fpr(<8 x i8>) = COPY $d1 + %2:fpr(<8 x i8>) = G_TRN2 %0, %1 + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -311,10 +311,10 @@ body: | ; CHECK-NEXT: [[TRN2v8i16_:%[0-9]+]]:fpr128 = TRN2v8i16 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v8i16_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 - %1:fpr(<8 x s16>) = COPY $q1 - %2:fpr(<8 x s16>) = G_TRN2 %0, %1 - $q0 = COPY %2(<8 x s16>) + %0:fpr(<8 x i16>) = COPY $q0 + %1:fpr(<8 x i16>) = COPY $q1 + %2:fpr(<8 x i16>) = G_TRN2 %0, %1 + $q0 = COPY %2(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -335,8 +335,8 @@ body: | ; CHECK-NEXT: [[TRN2v16i8_:%[0-9]+]]:fpr128 = TRN2v16i8 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[TRN2v16i8_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %1:fpr(<16 x s8>) = COPY $q1 - %2:fpr(<16 x s8>) = G_TRN2 %0, %1 - $q0 = COPY %2(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %1:fpr(<16 x i8>) = COPY $q1 + %2:fpr(<16 x i8>) = G_TRN2 %0, %1 + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir index c0b936332ca88..43b92865f0572 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-trunc.mir @@ -104,7 +104,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[COPY]].dsub ; CHECK-NEXT: $x0 = COPY [[COPY1]] - %0(s128) = COPY $q0 + %0(i128) = COPY $q0 %1(i64) = G_TRUNC %0 $x0 = COPY %1(i64) ... @@ -127,7 +127,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[COPY]].ssub ; CHECK-NEXT: $w0 = COPY [[COPY1]] - %0(s128) = COPY $q0 + %0(i128) = COPY $q0 %1(i32) = G_TRUNC %0 $w0 = COPY %1(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir index 33c56c4a6d044..287b82f9c8c5c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-truncstore-atomic.mir @@ -27,7 +27,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRW [[COPY2]], [[COPY]] :: (store release (s32)) + ; CHECK-NEXT: STLRW [[COPY2]], [[COPY]] :: (store release (i32)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -35,13 +35,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s32)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i32)) bb.3: RET_ReallyLR @@ -73,7 +73,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRH [[COPY2]], [[COPY]] :: (store release (s16)) + ; CHECK-NEXT: STLRH [[COPY2]], [[COPY]] :: (store release (i16)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -81,13 +81,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s16)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i16)) bb.3: RET_ReallyLR @@ -119,7 +119,7 @@ body: | ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 4 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[MOVi32imm]], %subreg.sub_32 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32 = COPY [[SUBREG_TO_REG]].sub_32 - ; CHECK-NEXT: STLRB [[COPY2]], [[COPY]] :: (store release (s8)) + ; CHECK-NEXT: STLRB [[COPY2]], [[COPY]] :: (store release (i8)) ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2: ; CHECK-NEXT: RET_ReallyLR @@ -127,13 +127,13 @@ body: | liveins: $w1, $x0 %0:gpr(p0) = COPY $x0 - %3:gpr(s32) = COPY $w1 + %3:gpr(i32) = COPY $w1 G_BRCOND %3, %bb.3 G_BR %bb.2 bb.2: - %8:gpr(s64) = G_CONSTANT i64 4 - G_STORE %8(s64), %0(p0) :: (store release (s8)) + %8:gpr(i64) = G_CONSTANT i64 4 + G_STORE %8(i64), %0(p0) :: (store release (i8)) bb.3: RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir index f6f9964e6babd..7cd67b2e338f6 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uadde.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_UADDE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_UADDE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_UADDE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_UADDE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_UADDO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_UADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_UADDO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_UADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADCSXr]] ; CHECK-NEXT: $x1 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_UADDE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_UADDE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[ADCSXr]] ; CHECK-NEXT: $x2 = COPY [[ADCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_UADDO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_UADDE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_UADDO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_UADDE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_UADDE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_UADDE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 3, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_UADDO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_UADDE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_UADDO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_UADDE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir index 9dcd085fc4fd5..d829f7092b07b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uaddo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[ADDSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_UADDO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_UADDO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[ADDSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_UADDO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_UADDO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,10 +75,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_UADDO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_UADDO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = ADDSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_UADDO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_UADDO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir index c15b668c5aa76..8a10c8dbbdc0a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ubfx.mir @@ -16,10 +16,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 0, 9 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 0 - %cst2:gpr(s32) = G_CONSTANT i32 10 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 0 + %cst2:gpr(i32) = G_CONSTANT i32 10 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 @@ -38,10 +38,10 @@ body: | ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 0, 9 ; CHECK: $x0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 0 - %cst2:gpr(s64) = G_CONSTANT i64 10 - %ubfx:gpr(s64) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 0 + %cst2:gpr(i64) = G_CONSTANT i64 10 + %ubfx:gpr(i64) = G_UBFX %copy, %cst1, %cst2 $x0 = COPY %ubfx RET_ReallyLR implicit $x0 @@ -63,10 +63,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 31, 31 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 31 - %cst2:gpr(s32) = G_CONSTANT i32 1 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 31 + %cst2:gpr(i32) = G_CONSTANT i32 1 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 --- @@ -83,10 +83,10 @@ body: | ; CHECK: %ubfx:gpr32 = UBFMWri %copy, 10, 14 ; CHECK: $w0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %cst1:gpr(s32) = G_CONSTANT i32 10 - %cst2:gpr(s32) = G_CONSTANT i32 5 - %ubfx:gpr(s32) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i32) = COPY $w0 + %cst1:gpr(i32) = G_CONSTANT i32 10 + %cst2:gpr(i32) = G_CONSTANT i32 5 + %ubfx:gpr(i32) = G_UBFX %copy, %cst1, %cst2 $w0 = COPY %ubfx RET_ReallyLR implicit $w0 @@ -105,9 +105,9 @@ body: | ; CHECK: %ubfx:gpr64 = UBFMXri %copy, 10, 14 ; CHECK: $x0 = COPY %ubfx ; CHECK: RET_ReallyLR implicit $x0 - %copy:gpr(s64) = COPY $x0 - %cst1:gpr(s64) = G_CONSTANT i64 10 - %cst2:gpr(s64) = G_CONSTANT i64 5 - %ubfx:gpr(s64) = G_UBFX %copy, %cst1, %cst2 + %copy:gpr(i64) = COPY $x0 + %cst1:gpr(i64) = G_CONSTANT i64 10 + %cst2:gpr(i64) = G_CONSTANT i64 5 + %ubfx:gpr(i64) = G_UBFX %copy, %cst1, %cst2 $x0 = COPY %ubfx RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir index 8a9f2cac79e9f..da58fa4815d94 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-unmerge.mir @@ -30,13 +30,13 @@ body: | ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi64lane]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 + %0:fpr(<2 x i64>) = COPY $q0 ; Since 2 * 64 = 128, we can just directly copy. - %2:fpr(s64), %3:fpr(s64) = G_UNMERGE_VALUES %0(<2 x s64>) + %2:fpr(i64), %3:fpr(i64) = G_UNMERGE_VALUES %0(<2 x i64>) - %1:fpr(<2 x s64>) = G_BUILD_VECTOR %2(s64), %3(s64) - $q0 = COPY %1(<2 x s64>) + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %3(i64) + $q0 = COPY %1(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -76,13 +76,13 @@ body: | ; CHECK-NEXT: [[INSvi32lane2:%[0-9]+]]:fpr128 = INSvi32lane [[INSvi32lane1]], 3, [[INSERT_SUBREG3]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi32lane2]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 + %0:fpr(<4 x i32>) = COPY $q0 ; Since 4 * 32 = 128, we can just directly copy. - %2:fpr(s32), %3:fpr(s32), %4:fpr(s32), %5:fpr(s32) = G_UNMERGE_VALUES %0(<4 x s32>) + %2:fpr(i32), %3:fpr(i32), %4:fpr(i32), %5:fpr(i32) = G_UNMERGE_VALUES %0(<4 x i32>) - %1:fpr(<4 x s32>) = G_BUILD_VECTOR %2(s32), %3(s32), %4(s32), %5(s32) - $q0 = COPY %1(<4 x s32>) + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %3(i32), %4(i32), %5(i32) + $q0 = COPY %1(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -112,15 +112,15 @@ body: | ; CHECK-NEXT: $h0 = COPY [[COPY1]] ; CHECK-NEXT: $h1 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1 - %0:fpr(<2 x s16>) = COPY $s0 + %0:fpr(<2 x i16>) = COPY $s0 ; Since 2 * 16 != 128, we need to widen using implicit defs. ; Note that we expect to reuse one of the INSERT_SUBREG results, as CPYi16 ; expects a lane > 0. - %2:fpr(s16), %3:fpr(s16) = G_UNMERGE_VALUES %0(<2 x s16>) + %2:fpr(i16), %3:fpr(i16) = G_UNMERGE_VALUES %0(<2 x i16>) - $h0 = COPY %2(s16) - $h1 = COPY %3(s16) + $h0 = COPY %2(i16) + $h1 = COPY %3(i16) RET_ReallyLR implicit $h0, implicit $h1 ... @@ -168,15 +168,15 @@ body: | ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi16lane2]].dsub ; CHECK-NEXT: $d0 = COPY [[COPY2]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s16>) = COPY $d0 + %0:fpr(<4 x i16>) = COPY $d0 ; Since 4 * 16 != 128, we need to widen using implicit defs. ; Note that we expect to reuse one of the INSERT_SUBREG results, as CPYi16 ; expects a lane > 0. - %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16) = G_UNMERGE_VALUES %0(<4 x s16>) + %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16) = G_UNMERGE_VALUES %0(<4 x i16>) - %1:fpr(<4 x s16>) = G_BUILD_VECTOR %2(s16), %3(s16), %4(s16), %5(s16) - $d0 = COPY %1(<4 x s16>) + %1:fpr(<4 x i16>) = G_BUILD_VECTOR %2(i16), %3(i16), %4(i16), %5(i16) + $d0 = COPY %1(<4 x i16>) RET_ReallyLR implicit $d0 ... --- @@ -236,13 +236,13 @@ body: | ; CHECK-NEXT: [[INSvi16lane6:%[0-9]+]]:fpr128 = INSvi16lane [[INSvi16lane5]], 7, [[INSERT_SUBREG7]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi16lane6]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<8 x s16>) = COPY $q0 + %0:fpr(<8 x i16>) = COPY $q0 ; Since 8 * 16 = 128, we can just directly copy. - %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16), %6:fpr(s16), %7:fpr(s16), %8:fpr(s16), %9:fpr(s16) = G_UNMERGE_VALUES %0(<8 x s16>) + %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16), %6:fpr(i16), %7:fpr(i16), %8:fpr(i16), %9:fpr(i16) = G_UNMERGE_VALUES %0(<8 x i16>) - %1:fpr(<8 x s16>) = G_BUILD_VECTOR %2:fpr(s16), %3:fpr(s16), %4:fpr(s16), %5:fpr(s16), %6:fpr(s16), %7:fpr(s16), %8:fpr(s16), %9:fpr(s16) - $q0 = COPY %1(<8 x s16>) + %1:fpr(<8 x i16>) = G_BUILD_VECTOR %2:fpr(i16), %3:fpr(i16), %4:fpr(i16), %5:fpr(i16), %6:fpr(i16), %7:fpr(i16), %8:fpr(i16), %9:fpr(i16) + $q0 = COPY %1(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -289,8 +289,8 @@ body: | ; CHECK-NEXT: $b6 = COPY [[DUPi8_5]] ; CHECK-NEXT: $b7 = COPY [[DUPi8_6]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<8 x s8>) = COPY $d0 - %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8) = G_UNMERGE_VALUES %0(<8 x s8>) + %0:fpr(<8 x i8>) = COPY $d0 + %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8) = G_UNMERGE_VALUES %0(<8 x i8>) $b0 = COPY %2 $b1 = COPY %3 $b2 = COPY %4 @@ -379,11 +379,11 @@ body: | ; CHECK-NEXT: [[INSvi8lane14:%[0-9]+]]:fpr128 = INSvi8lane [[INSvi8lane13]], 15, [[INSERT_SUBREG15]], 0 ; CHECK-NEXT: $q0 = COPY [[INSvi8lane14]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<16 x s8>) = COPY $q0 - %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8), %10:fpr(s8), %11:fpr(s8), %12:fpr(s8), %13:fpr(s8), %14:fpr(s8), %15:fpr(s8), %16:fpr(s8), %17:fpr(s8) = G_UNMERGE_VALUES %0(<16 x s8>) + %0:fpr(<16 x i8>) = COPY $q0 + %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8), %10:fpr(i8), %11:fpr(i8), %12:fpr(i8), %13:fpr(i8), %14:fpr(i8), %15:fpr(i8), %16:fpr(i8), %17:fpr(i8) = G_UNMERGE_VALUES %0(<16 x i8>) - %1:fpr(<16 x s8>) = G_BUILD_VECTOR %2:fpr(s8), %3:fpr(s8), %4:fpr(s8), %5:fpr(s8), %6:fpr(s8), %7:fpr(s8), %8:fpr(s8), %9:fpr(s8), %10:fpr(s8), %11:fpr(s8), %12:fpr(s8), %13:fpr(s8), %14:fpr(s8), %15:fpr(s8), %16:fpr(s8), %17:fpr(s8) - $q0 = COPY %1(<16 x s8>) + %1:fpr(<16 x i8>) = G_BUILD_VECTOR %2:fpr(i8), %3:fpr(i8), %4:fpr(i8), %5:fpr(i8), %6:fpr(i8), %7:fpr(i8), %8:fpr(i8), %9:fpr(i8), %10:fpr(i8), %11:fpr(i8), %12:fpr(i8), %13:fpr(i8), %14:fpr(i8), %15:fpr(i8), %16:fpr(i8), %17:fpr(i8) + $q0 = COPY %1(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -404,10 +404,10 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<2 x s32>), %2:fpr(<2 x s32>) = G_UNMERGE_VALUES %0(<4 x s32>) - $d0 = COPY %1(<2 x s32>) - $d1 = COPY %2(<2 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<2 x i32>), %2:fpr(<2 x i32>) = G_UNMERGE_VALUES %0(<4 x i32>) + $d0 = COPY %1(<2 x i32>) + $d1 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -430,10 +430,10 @@ body: | ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: $s1 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:fpr(<4 x s16>) = COPY $d0 - %1:fpr(<2 x s16>), %2:fpr(<2 x s16>) = G_UNMERGE_VALUES %0(<4 x s16>) - $s0 = COPY %1(<2 x s16>) - $s1 = COPY %2(<2 x s16>) + %0:fpr(<4 x i16>) = COPY $d0 + %1:fpr(<2 x i16>), %2:fpr(<2 x i16>) = G_UNMERGE_VALUES %0(<4 x i16>) + $s0 = COPY %1(<2 x i16>) + $s1 = COPY %2(<2 x i16>) RET_ReallyLR implicit $s0 ... --- @@ -454,10 +454,10 @@ body: | ; CHECK-NEXT: $d0 = COPY [[COPY1]] ; CHECK-NEXT: $d1 = COPY [[DUPi64_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1 - %0:fpr(s128) = COPY $q0 - %1:fpr(s64), %2:fpr(s64) = G_UNMERGE_VALUES %0(s128) - $d0 = COPY %1(s64) - $d1 = COPY %2(s64) + %0:fpr(i128) = COPY $q0 + %1:fpr(i64), %2:fpr(i64) = G_UNMERGE_VALUES %0(i128) + $d0 = COPY %1(i64) + $d1 = COPY %2(i64) RET_ReallyLR implicit $d0, implicit $d1 ... --- @@ -480,10 +480,10 @@ body: | ; CHECK-NEXT: $h0 = COPY [[COPY1]] ; CHECK-NEXT: $h1 = COPY [[DUPi16_]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1 - %0:fpr(s32) = COPY $s0 - %1:fpr(s16), %2:fpr(s16) = G_UNMERGE_VALUES %0(s32) - $h0 = COPY %1(s16) - $h1 = COPY %2(s16) + %0:fpr(i32) = COPY $s0 + %1:fpr(i16), %2:fpr(i16) = G_UNMERGE_VALUES %0(i32) + $h0 = COPY %1(i16) + $h1 = COPY %2(i16) RET_ReallyLR implicit $h0, implicit $h1 ... --- @@ -506,10 +506,10 @@ body: | ; CHECK-NEXT: $s0 = COPY [[COPY1]] ; CHECK-NEXT: $s1 = COPY [[DUPi32_]] ; CHECK-NEXT: RET_ReallyLR implicit $s0, implicit $s1 - %0:fpr(s64) = COPY $d0 - %1:fpr(s32), %2:fpr(s32) = G_UNMERGE_VALUES %0(s64) - $s0 = COPY %1(s32) - $s1 = COPY %2(s32) + %0:fpr(i64) = COPY $d0 + %1:fpr(i32), %2:fpr(i32) = G_UNMERGE_VALUES %0(i64) + $s0 = COPY %1(i32) + $s1 = COPY %2(i32) RET_ReallyLR implicit $s0, implicit $s1 ... --- @@ -540,12 +540,12 @@ body: | ; CHECK-NEXT: $h2 = COPY [[DUPi16_1]] ; CHECK-NEXT: $h3 = COPY [[DUPi16_2]] ; CHECK-NEXT: RET_ReallyLR implicit $h0, implicit $h1, implicit $h2, implicit $h3 - %0:fpr(s64) = COPY $d0 - %1:fpr(s16), %2:fpr(s16), %3:fpr(s16), %4:fpr(s16) = G_UNMERGE_VALUES %0(s64) - $h0 = COPY %1(s16) - $h1 = COPY %2(s16) - $h2 = COPY %3(s16) - $h3 = COPY %4(s16) + %0:fpr(i64) = COPY $d0 + %1:fpr(i16), %2:fpr(i16), %3:fpr(i16), %4:fpr(i16) = G_UNMERGE_VALUES %0(i64) + $h0 = COPY %1(i16) + $h1 = COPY %2(i16) + $h2 = COPY %3(i16) + $h3 = COPY %4(i16) RET_ReallyLR implicit $h0, implicit $h1, implicit $h2, implicit $h3 ... --- @@ -576,11 +576,11 @@ body: | ; CHECK-NEXT: $b2 = COPY [[DUPi8_1]] ; CHECK-NEXT: $b3 = COPY [[DUPi8_2]] ; CHECK-NEXT: RET_ReallyLR implicit $b0, implicit $b1, implicit $b2, implicit $b3 - %0:fpr(s32) = COPY $s0 - %1:fpr(s8), %2:fpr(s8), %3:fpr(s8), %4:fpr(s8) = G_UNMERGE_VALUES %0(s32) - $b0 = COPY %1(s8) - $b1 = COPY %2(s8) - $b2 = COPY %3(s8) - $b3 = COPY %4(s8) + %0:fpr(i32) = COPY $s0 + %1:fpr(i8), %2:fpr(i8), %3:fpr(i8), %4:fpr(i8) = G_UNMERGE_VALUES %0(i32) + $b0 = COPY %1(i8) + $b1 = COPY %2(i8) + $b2 = COPY %3(i8) + $b3 = COPY %4(i8) RET_ReallyLR implicit $b0, implicit $b1, implicit $b2, implicit $b3 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir index fa8799653a570..aa4f602ac09d7 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-usube.mir @@ -23,12 +23,12 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s64), %4:gpr(s32) = G_USUBE %0, %1, %2 - $x0 = COPY %3(s64) - $w1 = COPY %4(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i64), %4:gpr(i32) = G_USUBE %0, %1, %2 + $x0 = COPY %3(i64) + $w1 = COPY %4(i32) RET_ReallyLR implicit $x0, implicit $w1 ... ... @@ -54,12 +54,12 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SBCSWr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %2:gpr(s32) = G_CONSTANT i32 1 - %3:gpr(s32), %4:gpr(s32) = G_USUBE %0, %1, %2 - $w0 = COPY %3(s32) - $w1 = COPY %4(s32) + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %2:gpr(i32) = G_CONSTANT i32 1 + %3:gpr(i32), %4:gpr(i32) = G_USUBE %0, %1, %2 + $w0 = COPY %3(i32) + $w1 = COPY %4(i32) RET_ReallyLR implicit $w0, implicit $w1 ... ... @@ -85,14 +85,14 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %8:gpr(s64), %12:gpr(s32) = G_USUBO %0, %2 - %9:gpr(s64), %13:gpr(s32) = G_USUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %8:gpr(i64), %12:gpr(i32) = G_USUBO %0, %2 + %9:gpr(i64), %13:gpr(i32) = G_USUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -120,15 +120,15 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SBCSXr]] ; CHECK-NEXT: $x1 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %6:gpr(s32) = G_CONSTANT i32 1 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %0, %2, %6 - %9:gpr(s64), %13:gpr(s32) = G_USUBE %1, %3, %12 - $x0 = COPY %8(s64) - $x1 = COPY %9(s64) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %6:gpr(i32) = G_CONSTANT i32 1 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %0, %2, %6 + %9:gpr(i64), %13:gpr(i32) = G_USUBE %1, %3, %12 + $x0 = COPY %8(i64) + $x1 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1 ... ... @@ -160,19 +160,19 @@ body: | ; CHECK-NEXT: $x1 = COPY [[SBCSXr]] ; CHECK-NEXT: $x2 = COPY [[SBCSXr1]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %4:gpr(s64) = COPY $x4 - %5:gpr(s64) = COPY $x5 - %6:gpr(s64) = COPY $x6 - %7:gpr(s64), %11:gpr(s32) = G_USUBO %0, %4 - %8:gpr(s64), %12:gpr(s32) = G_USUBE %1, %5, %11 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %4:gpr(i64) = COPY $x4 + %5:gpr(i64) = COPY $x5 + %6:gpr(i64) = COPY $x6 + %7:gpr(i64), %11:gpr(i32) = G_USUBO %0, %4 + %8:gpr(i64), %12:gpr(i32) = G_USUBE %1, %5, %11 ; carry-in is not produced by previous instruction - %9:gpr(s64), %13:gpr(s32) = G_USUBE %2, %6, %11 - $x0 = COPY %7(s64) - $x1 = COPY %8(s64) - $x2 = COPY %9(s64) + %9:gpr(i64), %13:gpr(i32) = G_USUBE %2, %6, %11 + $x0 = COPY %7(i64) + $x1 = COPY %8(i64) + $x2 = COPY %9(i64) RET_ReallyLR implicit $x0, implicit $x1, implicit $x2 ... ... @@ -197,12 +197,12 @@ body: | ; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv ; CHECK-NEXT: $w0 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %2:gpr(s64) = COPY $x2 - %3:gpr(s64) = COPY $x3 - %4:gpr(s64), %5:gpr(s32) = G_USUBO %0, %2 - %6:gpr(s64), %7:gpr(s32) = G_USUBE %1, %3, %5 - $w0 = COPY %7(s32) + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %2:gpr(i64) = COPY $x2 + %3:gpr(i64) = COPY $x3 + %4:gpr(i64), %5:gpr(i32) = G_USUBO %0, %2 + %6:gpr(i64), %7:gpr(i32) = G_USUBE %1, %3, %5 + $w0 = COPY %7(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir index a9295194779c8..dd3b9453ac6b8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-usubo.mir @@ -22,9 +22,9 @@ body: | ; CHECK-NEXT: $w0 = COPY [[SUBSWrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1 - %0:gpr(s32) = COPY $w0 - %1:gpr(s32) = COPY $w1 - %3:gpr(s32), %4:gpr(s32) = G_USUBO %0, %1 + %0:gpr(i32) = COPY $w0 + %1:gpr(i32) = COPY $w1 + %3:gpr(i32), %4:gpr(i32) = G_USUBO %0, %1 $w0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $w0, implicit $w1 @@ -50,9 +50,9 @@ body: | ; CHECK-NEXT: $x0 = COPY [[SUBSXrr]] ; CHECK-NEXT: $w1 = COPY [[CSINCWr]] ; CHECK-NEXT: RET_ReallyLR implicit $x0, implicit $w1 - %0:gpr(s64) = COPY $x0 - %1:gpr(s64) = COPY $x1 - %3:gpr(s64), %4:gpr(s32) = G_USUBO %0, %1 + %0:gpr(i64) = COPY $x0 + %1:gpr(i64) = COPY $x1 + %3:gpr(i64), %4:gpr(i32) = G_USUBO %0, %1 $x0 = COPY %3 $w1 = COPY %4 RET_ReallyLR implicit $x0, implicit $w1 @@ -75,9 +75,9 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 16 - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy, %constant + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 16 + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy, %constant $w0 = COPY %add RET_ReallyLR implicit $w0 @@ -100,12 +100,12 @@ body: | ; CHECK-NEXT: %add:gpr32 = SUBSWrs %copy1, %copy2, 16, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy1:gpr(s32) = COPY $w0 - %copy2:gpr(s32) = COPY $w1 - %constant:gpr(s32) = G_CONSTANT i32 16 - %shift:gpr(s32) = G_SHL %copy2(s32), %constant(s32) - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy1, %shift - $w0 = COPY %add(s32) + %copy1:gpr(i32) = COPY $w0 + %copy2:gpr(i32) = COPY $w1 + %constant:gpr(i32) = G_CONSTANT i32 16 + %shift:gpr(i32) = G_SHL %copy2(i32), %constant(i32) + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy1, %shift + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -126,10 +126,10 @@ body: | ; CHECK-NEXT: %add:gpr32 = ADDSWri %copy, 16, 0, implicit-def $nzcv ; CHECK-NEXT: $w0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %copy:gpr(s32) = COPY $w0 - %constant:gpr(s32) = G_CONSTANT i32 -16 - %add:gpr(s32), %overflow:gpr(s32) = G_USUBO %copy, %constant - $w0 = COPY %add(s32) + %copy:gpr(i32) = COPY $w0 + %constant:gpr(i32) = G_CONSTANT i32 -16 + %add:gpr(i32), %overflow:gpr(i32) = G_USUBO %copy, %constant + $w0 = COPY %add(i32) RET_ReallyLR implicit $w0 ... @@ -151,11 +151,11 @@ body: | ; CHECK-NEXT: %add:gpr64 = SUBSXrx %reg0, %reg1, 18, implicit-def $nzcv ; CHECK-NEXT: $x0 = COPY %add ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:gpr(s64) = COPY $x0 - %reg1:gpr(s32) = COPY $w0 - %ext:gpr(s64) = G_ZEXT %reg1(s32) - %cst:gpr(s64) = G_CONSTANT i64 2 - %shift:gpr(s64) = G_SHL %ext, %cst(s64) - %add:gpr(s64), %flags:gpr(s32) = G_USUBO %reg0, %shift - $x0 = COPY %add(s64) + %reg0:gpr(i64) = COPY $x0 + %reg1:gpr(i32) = COPY $w0 + %ext:gpr(i64) = G_ZEXT %reg1(i32) + %cst:gpr(i64) = G_CONSTANT i64 2 + %shift:gpr(i64) = G_SHL %ext, %cst(i64) + %add:gpr(i64), %flags:gpr(i32) = G_USUBO %reg0, %shift + $x0 = COPY %add(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir index 83ca512889cc1..e5925852058e3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-uzp.mir @@ -22,10 +22,10 @@ body: | ; CHECK-NEXT: [[UZP1v4i32_:%[0-9]+]]:fpr128 = UZP1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[UZP1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_UZP1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_UZP1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -46,10 +46,10 @@ body: | ; CHECK-NEXT: [[UZP2v4i32_:%[0-9]+]]:fpr128 = UZP2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[UZP2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_UZP2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_UZP2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir index 4ee74f3a952a1..8c5cd27e41ca3 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-icmp.mir @@ -510,12 +510,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(eq), %7(<2 x i32>), %8 @@ -800,12 +800,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ugt), %7(<2 x i32>), %8 @@ -1090,12 +1090,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(uge), %7(<2 x i32>), %8 @@ -1380,12 +1380,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ult), %7(<2 x i32>), %8 @@ -1670,12 +1670,12 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %13:gpr(s32) = G_CONSTANT i32 65535 - %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(s32), %13(s32) + %13:gpr(i32) = G_CONSTANT i32 65535 + %14:fpr(<2 x i32>) = G_BUILD_VECTOR %13(i32), %13(i32) %15:fpr(<2 x i32>) = COPY %2(<2 x i32>) %7:fpr(<2 x i32>) = G_AND %15, %14 - %10:gpr(s32) = G_CONSTANT i32 65535 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 65535 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %8:fpr(<2 x i32>) = G_AND %12, %11 %9:fpr(<2 x i32>) = G_ICMP intpred(ule), %7(<2 x i32>), %8 @@ -1966,13 +1966,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2264,13 +2264,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2562,13 +2562,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) @@ -2860,13 +2860,13 @@ body: | ; CHECK-NEXT: RET_ReallyLR implicit $d0 %2:fpr(<2 x i32>) = COPY $d0 %3:fpr(<2 x i32>) = COPY $d1 - %14:gpr(s32) = G_CONSTANT i32 16 - %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(s32), %14(s32) + %14:gpr(i32) = G_CONSTANT i32 16 + %15:fpr(<2 x i32>) = G_BUILD_VECTOR %14(i32), %14(i32) %16:fpr(<2 x i32>) = COPY %2(<2 x i32>) %17:fpr(<2 x i32>) = G_SHL %16, %15(<2 x i32>) %7:fpr(<2 x i32>) = G_ASHR %17, %15(<2 x i32>) - %10:gpr(s32) = G_CONSTANT i32 16 - %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(s32), %10(s32) + %10:gpr(i32) = G_CONSTANT i32 16 + %11:fpr(<2 x i32>) = G_BUILD_VECTOR %10(i32), %10(i32) %12:fpr(<2 x i32>) = COPY %3(<2 x i32>) %13:fpr(<2 x i32>) = G_SHL %12, %11(<2 x i32>) %8:fpr(<2 x i32>) = G_ASHR %13, %11(<2 x i32>) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir index 605ab99094719..9371e2eac5e4a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-vector-shift.mir @@ -58,8 +58,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[SHLv2i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 @@ -94,8 +94,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[USHLv2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 40 - %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 40 + %1:fpr(<2 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 @@ -159,8 +159,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[SHLv4i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<4 x i32>) = COPY $q0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(s32), %2(s32), %2(s32), %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<4 x i32>) = G_BUILD_VECTOR %2(i32), %2(i32), %2(i32), %2(i32) %3:fpr(<4 x i32>) = G_SHL %0, %1(<4 x i32>) $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 @@ -224,8 +224,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[SHLv2i64_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<2 x i64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 24 - %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(s64), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 24 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %2(i64) %3:fpr(<2 x i64>) = G_SHL %0, %1(<2 x i64>) $q0 = COPY %3(<2 x i64>) RET_ReallyLR implicit $q0 @@ -261,8 +261,8 @@ body: | ; CHECK-NEXT: $q0 = COPY [[USHLv2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 %0:fpr(<2 x i64>) = COPY $q0 - %2:gpr(s64) = G_CONSTANT i64 70 - %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(s64), %2(s64) + %2:gpr(i64) = G_CONSTANT i64 70 + %1:fpr(<2 x i64>) = G_BUILD_VECTOR %2(i64), %2(i64) %3:fpr(<2 x i64>) = G_SHL %0, %1(<2 x i64>) $q0 = COPY %3(<2 x i64>) RET_ReallyLR implicit $q0 @@ -619,8 +619,8 @@ body: | ; CHECK-NEXT: $d0 = COPY [[SHLv2i32_shift]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 %0:fpr(<2 x i32>) = COPY $d0 - %2:gpr(s32) = G_CONSTANT i32 24 - %1:fpr(<2 x i32>) = G_DUP %2(s32) + %2:gpr(i32) = G_CONSTANT i32 24 + %1:fpr(<2 x i32>) = G_DUP %2(i32) %3:fpr(<2 x i32>) = G_SHL %0, %1(<2 x i32>) $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir index d22305e441936..68b396029536a 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-with-no-legality-check.mir @@ -260,11 +260,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: $noreg = PATCHABLE_RET [[LDRBBui]] %2:gpr(p0) = COPY $x0 - %0:gpr(s32) = G_LOAD %2(p0) :: (load (s8)) - $noreg = PATCHABLE_RET %0(s32) + %0:gpr(i32) = G_LOAD %2(p0) :: (load (i8)) + $noreg = PATCHABLE_RET %0(i32) ... # The rules that generated this test has changed. The generator should be rerun @@ -288,14 +288,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBui:%[0-9]+]]:fpr8 = LDRBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY [[LDRBui]] ; CHECK-NEXT: [[UBFMWri:%[0-9]+]]:gpr32 = UBFMWri [[COPY1]], 0, 7 ; CHECK-NEXT: $noreg = PATCHABLE_RET [[UBFMWri]] %2:gpr(p0) = COPY $x0 - %0:fpr(s8) = G_LOAD %2(p0) :: (load (s8)) - %1:gpr(s32) = G_ZEXT %0(s8) - $noreg = PATCHABLE_RET %1(s32) + %0:fpr(i8) = G_LOAD %2(p0) :: (load (i8)) + %1:gpr(i32) = G_ZEXT %0(i8) + $noreg = PATCHABLE_RET %1(i32) ... --- diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir index e6b400f324133..e0964ac628db4 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zext-as-copy.mir @@ -23,13 +23,13 @@ body: | ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64common = IMPLICIT_DEF - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[DEF]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: [[ANDXri:%[0-9]+]]:gpr64sp = ANDXri [[COPY]], 4096 ; CHECK-NEXT: $x0 = COPY [[ANDXri]] %3:gpr(p0) = G_IMPLICIT_DEF - %2:gpr(i8) = G_LOAD %3(p0) :: (load (s8)) + %2:gpr(i8) = G_LOAD %3(p0) :: (load (i8)) %4:gpr(i64) = G_ZEXT %2(i8) %5:gpr(i64) = G_CONSTANT i64 1 %6:gpr(i64) = G_AND %4, %5 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir index b6b386acdbd9a..3ca1335fe7524 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zextload.mir @@ -13,10 +13,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] %0:gpr(p0) = COPY $x0 - %1:gpr(i32) = G_ZEXTLOAD %0 :: (load (s16)) + %1:gpr(i32) = G_ZEXTLOAD %0 :: (load (i16)) $w0 = COPY %1(i32) ... --- @@ -31,11 +31,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[LDRHHui]] ; CHECK-NEXT: $w0 = COPY [[COPY1]] %0:gpr(p0) = COPY $x0 - %1:gpr(s16) = G_LOAD %0 :: (load (s16)) + %1:gpr(i16) = G_LOAD %0 :: (load (i16)) %2:gpr(i32) = G_ZEXT %1 $w0 = COPY %2(i32) ... @@ -51,12 +51,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (s32)) + ; CHECK-NEXT: [[LDRWui:%[0-9]+]]:gpr32 = LDRWui [[COPY]], 0 :: (load (i32)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRWui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s32)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i32)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -73,12 +73,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRHHui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s16)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i16)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -95,12 +95,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG [[LDRBBui]], %subreg.sub_32 ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:gpr(p0) = COPY $x0 - %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (s8)) + %2:gpr(i64) = G_ZEXTLOAD %0(p0) :: (load (i8)) $x0 = COPY %2(i64) RET_ReallyLR implicit $x0 @@ -117,11 +117,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (i8)) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -138,11 +138,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load (i16)) $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 @@ -160,11 +160,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load unordered (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load unordered (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -182,11 +182,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load monotonic (s8)) + ; CHECK-NEXT: [[LDRBBui:%[0-9]+]]:gpr32 = LDRBBui [[COPY]], 0 :: (load monotonic (i8)) ; CHECK-NEXT: $w0 = COPY [[LDRBBui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -204,11 +204,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (s8)) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load acquire (i8)) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -226,11 +226,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load seq_cst (s8)) + ; CHECK-NEXT: [[LDARB:%[0-9]+]]:gpr32 = LDARB [[COPY]] :: (load seq_cst (i8)) ; CHECK-NEXT: $w0 = COPY [[LDARB]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (s8)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (i8)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -248,11 +248,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load unordered (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load unordered (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load unordered (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -270,11 +270,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load monotonic (s16)) + ; CHECK-NEXT: [[LDRHHui:%[0-9]+]]:gpr32 = LDRHHui [[COPY]], 0 :: (load monotonic (i16)) ; CHECK-NEXT: $w0 = COPY [[LDRHHui]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load monotonic (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -292,11 +292,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load acquire (s16)) + ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load acquire (i16)) ; CHECK-NEXT: $w0 = COPY [[LDARH]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load acquire (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 @@ -314,11 +314,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0 - ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load seq_cst (s16)) + ; CHECK-NEXT: [[LDARH:%[0-9]+]]:gpr32 = LDARH [[COPY]] :: (load seq_cst (i16)) ; CHECK-NEXT: $w0 = COPY [[LDARH]] ; CHECK-NEXT: RET_ReallyLR implicit $w0 %0:gpr(p0) = COPY $x0 - %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (s16)) + %2:gpr(i32) = G_ZEXTLOAD %0(p0) :: (load seq_cst (i16)) $w0 = COPY %2 RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir index da25425708244..6f7f617782878 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-zip.mir @@ -23,10 +23,10 @@ body: | ; CHECK-NEXT: [[ZIP1v2i32_:%[0-9]+]]:fpr64 = ZIP1v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[ZIP1v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_ZIP1 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_ZIP1 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -47,10 +47,10 @@ body: | ; CHECK-NEXT: [[ZIP1v2i64_:%[0-9]+]]:fpr128 = ZIP1v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP1v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_ZIP1 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_ZIP1 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -70,10 +70,10 @@ body: | ; CHECK-NEXT: [[ZIP1v4i32_:%[0-9]+]]:fpr128 = ZIP1v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP1v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_ZIP1 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_ZIP1 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -94,10 +94,10 @@ body: | ; CHECK-NEXT: [[ZIP2v2i32_:%[0-9]+]]:fpr64 = ZIP2v2i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $d0 = COPY [[ZIP2v2i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:fpr(<2 x s32>) = COPY $d0 - %1:fpr(<2 x s32>) = COPY $d1 - %2:fpr(<2 x s32>) = G_ZIP2 %0, %1 - $d0 = COPY %2(<2 x s32>) + %0:fpr(<2 x i32>) = COPY $d0 + %1:fpr(<2 x i32>) = COPY $d1 + %2:fpr(<2 x i32>) = G_ZIP2 %0, %1 + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... --- @@ -118,10 +118,10 @@ body: | ; CHECK-NEXT: [[ZIP2v2i64_:%[0-9]+]]:fpr128 = ZIP2v2i64 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP2v2i64_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<2 x s64>) = COPY $q0 - %1:fpr(<2 x s64>) = COPY $q1 - %2:fpr(<2 x s64>) = G_ZIP2 %0, %1 - $q0 = COPY %2(<2 x s64>) + %0:fpr(<2 x i64>) = COPY $q0 + %1:fpr(<2 x i64>) = COPY $q1 + %2:fpr(<2 x i64>) = G_ZIP2 %0, %1 + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -141,8 +141,8 @@ body: | ; CHECK-NEXT: [[ZIP2v4i32_:%[0-9]+]]:fpr128 = ZIP2v4i32 [[COPY]], [[COPY1]] ; CHECK-NEXT: $q0 = COPY [[ZIP2v4i32_]] ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:fpr(<4 x s32>) = COPY $q0 - %1:fpr(<4 x s32>) = COPY $q1 - %2:fpr(<4 x s32>) = G_ZIP2 %0, %1 - $q0 = COPY %2(<4 x s32>) + %0:fpr(<4 x i32>) = COPY $q0 + %1:fpr(<4 x i32>) = COPY $q1 + %2:fpr(<4 x i32>) = G_ZIP2 %0, %1 + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 From 16038020c99a9d7058c665ff867b8930dfd5a38e Mon Sep 17 00:00:00 2001 From: Ziqing Luo Date: Thu, 9 Jul 2026 12:18:42 -0700 Subject: [PATCH 006/125] [SSAF] Replace std::set with SetVector for deterministic order of contributor Decls (#208346) The container `std::set` created a non-deterministic traversal order for a contributor's `Decls`, making the resulting representative `Decls[0]` non-deterministic as well. Also fix typos in assertion messages. Follow-up to #204482. --- .../ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp | 4 ++-- .../lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp index 667ef69606aad..d9a168e11d1a7 100644 --- a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp +++ b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.cpp @@ -12,7 +12,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/AST/ExprCXX.h" -#include +#include "llvm/ADT/SetVector.h" using namespace clang; @@ -32,7 +32,7 @@ namespace { // Traverses the AST and finds contributors. class ContributorFinder : public DynamicRecursiveASTVisitor { public: - std::set Contributors; + llvm::SetVector Contributors; ContributorFinder() { ShouldVisitTemplateInstantiations = true; diff --git a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h index 152168ea73b54..05c71ed83853b 100644 --- a/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h +++ b/clang/lib/ScalableStaticAnalysis/Analyses/SSAFAnalysesCommon.h @@ -110,9 +110,9 @@ void extractAndAddSummaries(TUSummaryExtractor &Extractor, findContributors(Ctx, Contributors); for (const auto &[Cano, Decls] : Contributors) { assert(!Decls.empty() && - "'findContributors' guarantess that 'Decls' are non-empty"); + "'findContributors' guarantees that 'Decls' are non-empty"); assert(!Decls[0]->isImplicit() && - "'findContributors' guarantess that 'Decls' are non-implicit"); + "'findContributors' guarantees that 'Decls' are non-implicit"); // Templates are skipped, but their instantiations are handled. The idea // is that we can conclude facts about a template through all of its From 72cb2762b2144eec53bfb4a0e7755d5b94ba6841 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 9 Jul 2026 15:24:58 -0400 Subject: [PATCH 007/125] [SLP][NFC]Silence warning for unused variable, NFC Reviewers: Pull Request: https://github.com/llvm/llvm-project/pull/208536 --- llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 880cb87bd9923..48fb4beba6935 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -1073,7 +1073,7 @@ class BinOpSameOpcodeHelper { /// left hand side (0). static std::pair isBinOpWithConstant(const Instruction *I) { - unsigned Opcode = I->getOpcode(); + [[maybe_unused]] unsigned Opcode = I->getOpcode(); assert(binary_search(SupportedOp, Opcode) && "Unsupported opcode."); (void)SupportedOp; auto *BinOp = cast(I); From bba373c7a20c280673035a7ae3c01937ca49ee3b Mon Sep 17 00:00:00 2001 From: "Ivan R. Ivanov" Date: Thu, 9 Jul 2026 21:30:55 +0200 Subject: [PATCH 008/125] [flang][Lower] Track whether a call to a function is to an intrinsic (#208000) Add an attribute which indicates that a call is to an intrinsic function. Intrinsic here means that the function declaration was found in a module found in the intrinsic path. This allows us to, when optimizing, make sure that we correctly identify calls to intrinsic functions whose behaviours we know, and not user-defined functions whose names happen to match. --- .../flang/Optimizer/Dialect/FIRAttr.td | 9 +- flang/lib/Lower/CallInterface.cpp | 4 + flang/test/Lower/CUDA/cuda-device-proc.cuf | 76 +++++----- flang/test/Lower/CUDA/cuda-libdevice.cuf | 130 +++++++++--------- .../OpenMP/threadprivate-default-clause.f90 | 4 +- 5 files changed, 116 insertions(+), 107 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.td b/flang/include/flang/Optimizer/Dialect/FIRAttr.td index 3bb1f443f3a5d..c53a2b869e968 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRAttr.td +++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.td @@ -78,14 +78,19 @@ def FIRfuncPure : I32BitEnumAttrCaseBit<"pure", 1>; def FIRfuncNonRecursive : I32BitEnumAttrCaseBit<"non_recursive", 2>; def FIRfuncSimple : I32BitEnumAttrCaseBit<"simple", 3>; def FIRfuncBind_c : I32BitEnumAttrCaseBit<"bind_c", 4>; -def FIRfuncRecursive : I32BitEnumAttrCaseBit<"recursive", 5>; +def FIRfuncRecursive : I32BitEnumAttrCaseBit<"recursive", 5>; +/// We also track whether a procedure call is to an "intrinsic", meaning that the +/// callee was found in an instrinsic module. This allows us to make sure calls are +/// to known intrinsic functions and not user-defined functions with the same +/// name when optimizing. +def FIRfuncIntrinsic : I32BitEnumAttrCaseBit<"intrinsic", 6>; def fir_FortranProcedureFlagsEnum : I32BitEnumAttr<"FortranProcedureFlagsEnum", "Fortran procedure attributes", [FIRfuncNoAttributes, FIRfuncElemental, FIRfuncPure, FIRfuncNonRecursive, FIRfuncSimple, FIRfuncBind_c, - FIRfuncRecursive]> { + FIRfuncRecursive, FIRfuncIntrinsic]> { let separator = ", "; let cppNamespace = "::fir"; let genSpecializedAttr = 0; diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 6ca309a05d438..c84c0b27505bb 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -9,6 +9,7 @@ #include "flang/Lower/CallInterface.h" #include "flang/Evaluate/fold.h" #include "flang/Lower/Bridge.h" +#include "flang/Lower/ConvertCall.h" #include "flang/Lower/Mangler.h" #include "flang/Lower/OpenACC.h" #include "flang/Lower/PFTBuilder.h" @@ -1592,6 +1593,9 @@ Fortran::lower::CallInterface::getProcedureAttrs( flags = flags | fir::FortranProcedureFlagsEnum::recursive; } } + if constexpr (std::is_same_v) + if (Fortran::lower::isIntrinsicModuleProcRef(side().getCallDescription())) + flags = flags | fir::FortranProcedureFlagsEnum::intrinsic; if (flags != fir::FortranProcedureFlagsEnum::none) return fir::FortranProcedureFlagsEnumAttr::get(mlirContext, flags); return nullptr; diff --git a/flang/test/Lower/CUDA/cuda-device-proc.cuf b/flang/test/Lower/CUDA/cuda-device-proc.cuf index 81286dec57590..f252461700eda 100644 --- a/flang/test/Lower/CUDA/cuda-device-proc.cuf +++ b/flang/test/Lower/CUDA/cuda-device-proc.cuf @@ -151,44 +151,44 @@ end ! CHECK: %{{.*}} = nvvm.read.ptx.sreg.clock64 : i64 ! CHECK: %{{.*}} = nvvm.read.ptx.sreg.globaltimer : i64 -! CHECK: %{{.*}} = fir.call @__nv_popc(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_popcll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_ffs(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_ffsll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_brev(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_brevll(%{{.*}}) proc_attrs fastmath : (i64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_clz(%{{.*}}) proc_attrs fastmath : (i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_clzll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_fast_cosf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__ddiv_rn(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_rz(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_ru(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__ddiv_rd(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2float_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2int_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_double2uint_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_mul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_umul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_fast_powf(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ull2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_float2half_rn(%{{.*}}) proc_attrs fastmath : (f32) -> f16 -! CHECK: %{{.*}} = fir.call @__nv_half2float(%{{.*}}) proc_attrs fastmath : (f16) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 -! CHECK: %{{.*}} = fir.call @__nv_ll2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_popc(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_popcll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_ffs(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_ffsll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_brev(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_brevll(%{{.*}}) proc_attrs fastmath : (i64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_clz(%{{.*}}) proc_attrs fastmath : (i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_clzll(%{{.*}}) proc_attrs fastmath : (i64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_fast_cosf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__ddiv_rn(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_rz(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_ru(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__ddiv_rd(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f64, f64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2float_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2int_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2uint_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_mul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_umul24(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_fast_powf(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ull2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_float2half_rn(%{{.*}}) proc_attrs fastmath : (f32) -> f16 +! CHECK: %{{.*}} = fir.call @__nv_half2float(%{{.*}}) proc_attrs fastmath : (f16) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_ll2double_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f64 subroutine host1() integer, device :: a(32) diff --git a/flang/test/Lower/CUDA/cuda-libdevice.cuf b/flang/test/Lower/CUDA/cuda-libdevice.cuf index 7c6eda21a6e75..7718a84c08309 100644 --- a/flang/test/Lower/CUDA/cuda-libdevice.cuf +++ b/flang/test/Lower/CUDA/cuda-libdevice.cuf @@ -9,7 +9,7 @@ attributes(global) subroutine test_sad() end subroutine ! CHECK-LABEL: _QPtest_sad -! CHECK: %{{.*}} = fir.call @__nv_sad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_sad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 attributes(global) subroutine test_usad() integer :: res @@ -18,7 +18,7 @@ attributes(global) subroutine test_usad() end subroutine ! CHECK-LABEL: _QPtest_usad -! CHECK: %{{.*}} = fir.call @__nv_usad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_usad(%{{.*}}, %{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32, i32) -> i32 attributes(global) subroutine test_dsqrt_rX() double precision :: res @@ -30,10 +30,10 @@ attributes(global) subroutine test_dsqrt_rX() end subroutine ! CHECK-LABEL: _QPtest_dsqrt_rx -! CHECK: %{{.*}} = fir.call @__dsqrt_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__dsqrt_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__dsqrt_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 attributes(global) subroutine test_uint2float_rX() real :: res @@ -45,10 +45,10 @@ attributes(global) subroutine test_uint2float_rX() end subroutine ! CHECK-LABEL: _QPtest_uint2float_rx -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_uint2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_uint2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_uint2double_rn() double precision :: res @@ -57,7 +57,7 @@ attributes(global) subroutine test_uint2double_rn() end subroutine ! CHECK-LABEL: _QPtest_uint2double_rn -! CHECK: %{{.*}} = fir.call @__nv_uint2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_uint2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 attributes(global) subroutine test_ull2dloat_rX() real :: res @@ -69,10 +69,10 @@ attributes(global) subroutine test_ull2dloat_rX() end subroutine ! CHECK-LABEL: _QPtest_ull2dloat_rx -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ull2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ull2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 attributes(global) subroutine test_log() real :: res @@ -83,9 +83,9 @@ attributes(global) subroutine test_log() end subroutine ! CHECK-LABEL: _QPtest_log -! CHECK: %{{.*}} = fir.call @__nv_fast_logf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_log2f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_log10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_logf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_log2f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_log10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_sincosf() real :: r, s, c @@ -93,7 +93,7 @@ attributes(global) subroutine test_sincosf() end subroutine ! CHECK-LABEL: _QPtest_sincosf -! CHECK: fir.call @__nv_fast_sincosf(%{{.*}}, %{{.*}}#0, %{{.*}}#0) proc_attrs fastmath : (f32, !fir.ref, !fir.ref) -> () +! CHECK: fir.call @__nv_fast_sincosf(%{{.*}}, %{{.*}}#0, %{{.*}}#0) proc_attrs fastmath : (f32, !fir.ref, !fir.ref) -> () attributes(global) subroutine test_sinf() real :: res @@ -102,7 +102,7 @@ attributes(global) subroutine test_sinf() end subroutine ! CHECK-LABEL: _QPtest_sinf -! CHECK: %{{.*}} = fir.call @__nv_fast_sinf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_sinf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_tanf() real :: res @@ -111,7 +111,7 @@ attributes(global) subroutine test_tanf() end subroutine ! CHECK-LABEL: _QPtest_tanf -! CHECK: %{{.*}} = fir.call @__nv_fast_tanf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_tanf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_exp() real :: res @@ -121,8 +121,8 @@ attributes(global) subroutine test_exp() end subroutine ! CHECK-LABEL: _QPtest_exp -! CHECK: %{{.*}} = fir.call @__nv_fast_expf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_fast_exp10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_expf(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_exp10f(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_double2ll_rX() integer(8) :: res @@ -134,10 +134,10 @@ attributes(global) subroutine test_double2ll_rX() end subroutine ! CHECK-LABEL: _QPtest_double2ll_rx -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ll_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ll_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_drcp_rX() double precision :: res @@ -149,10 +149,10 @@ attributes(global) subroutine test_drcp_rX() end subroutine ! CHECK-LABEL: _QPtest_drcp_rx -! CHECK: %{{.*}} = fir.call @__drcp_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 -! CHECK: %{{.*}} = fir.call @__drcp_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rd(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rn(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_ru(%{{.*}}) proc_attrs fastmath : (f64) -> f64 +! CHECK: %{{.*}} = fir.call @__drcp_rz(%{{.*}}) proc_attrs fastmath : (f64) -> f64 attributes(global) subroutine test_double2ull_rX() integer(8) :: res @@ -164,10 +164,10 @@ attributes(global) subroutine test_double2ull_rX() end subroutine ! CHECK-LABEL: _QPtest_double2ull_rx -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_double2ull_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rd(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rn(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_ru(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double2ull_rz(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_saturatef() real :: res @@ -176,7 +176,7 @@ attributes(global) subroutine test_saturatef() end subroutine ! CHECK-LABEL: _QPtest_saturatef -! CHECK: %{{.*}} = fir.call @__nv_saturatef(%{{.*}}) proc_attrs fastmath : (f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_saturatef(%{{.*}}) proc_attrs fastmath : (f32) -> f32 attributes(global) subroutine test_float2ll_rX() integer(8) :: res @@ -188,10 +188,10 @@ attributes(global) subroutine test_float2ll_rX() end subroutine ! CHECK-LABEL: _QPtest_float2ll_rx -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i64 -! CHECK: %{{.*}} = fir.call @__nv_float2ll_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_float2ll_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i64 attributes(global) subroutine test_ll2float_rX() real :: res @@ -203,10 +203,10 @@ attributes(global) subroutine test_ll2float_rX() end subroutine ! CHECK-LABEL: _QPtest_ll2float_rx -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_ll2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rd(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rn(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_ru(%{{.*}}) proc_attrs fastmath : (i64) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_ll2float_rz(%{{.*}}) proc_attrs fastmath : (i64) -> f32 attributes(global) subroutine test_int2float_rX() real :: res @@ -218,10 +218,10 @@ attributes(global) subroutine test_int2float_rX() end subroutine ! CHECK-LABEL: _QPtest_int2float_rx -! CHECK: %{{.*}} = fir.call @__nv_int2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 -! CHECK: %{{.*}} = fir.call @__nv_int2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rd(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_ru(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int2float_rz(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_float2int_rX() integer :: res @@ -233,10 +233,10 @@ attributes(global) subroutine test_float2int_rX() end subroutine ! CHECK-LABEL: _QPtest_float2int_rx -! CHECK: %{{.*}} = fir.call @__nv_float2int_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2int_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2int_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_float2uint_rX() integer :: res @@ -248,10 +248,10 @@ attributes(global) subroutine test_float2uint_rX() end subroutine ! CHECK-LABEL: _QPtest_float2uint_rx -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 -! CHECK: %{{.*}} = fir.call @__nv_float2uint_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rd(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rn(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_ru(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float2uint_rz(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_int2double_rn() double precision :: res @@ -260,7 +260,7 @@ attributes(global) subroutine test_int2double_rn() end subroutine ! CHECK-LABEL: _QPtest_int2double_rn -! CHECK: %{{.*}} = fir.call @__nv_int2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_int2double_rn(%{{.*}}) proc_attrs fastmath : (i32) -> f64 attributes(global) subroutine test_fdividef() real :: res @@ -269,7 +269,7 @@ attributes(global) subroutine test_fdividef() end subroutine ! CHECK-LABEL: _QPtest_fdividef -! CHECK: %{{.*}} = fir.call @__nv_fast_fdividef(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_fast_fdividef(%{{.*}}, %{{.*}}) proc_attrs fastmath : (f32, f32) -> f32 attributes(global) subroutine test_double_as_longlong() integer(8) :: res @@ -278,7 +278,7 @@ attributes(global) subroutine test_double_as_longlong() end subroutine ! CHECK-LABEL: _QPtest_double_as_longlong -! CHECK: %{{.*}} = fir.call @__nv_double_as_longlong(%{{.*}}) proc_attrs fastmath : (f64) -> i64 +! CHECK: %{{.*}} = fir.call @__nv_double_as_longlong(%{{.*}}) proc_attrs fastmath : (f64) -> i64 attributes(global) subroutine test_longlong_as_double() integer(8) :: i @@ -287,7 +287,7 @@ attributes(global) subroutine test_longlong_as_double() end subroutine ! CHECK-LABEL: _QPtest_longlong_as_double -! CHECK: %{{.*}} = fir.call @__nv_longlong_as_double(%{{.*}}) proc_attrs fastmath : (i64) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_longlong_as_double(%{{.*}}) proc_attrs fastmath : (i64) -> f64 attributes(global) subroutine test_int_as_float() integer :: i @@ -296,7 +296,7 @@ attributes(global) subroutine test_int_as_float() end subroutine ! CHECK-LABEL: _QPtest_int_as_float -! CHECK: %{{.*}} = fir.call @__nv_int_as_float(%{{.*}}) proc_attrs fastmath : (i32) -> f32 +! CHECK: %{{.*}} = fir.call @__nv_int_as_float(%{{.*}}) proc_attrs fastmath : (i32) -> f32 attributes(global) subroutine test_float_as_int() integer :: res @@ -305,7 +305,7 @@ attributes(global) subroutine test_float_as_int() end subroutine ! CHECK-LABEL: _QPtest_float_as_int -! CHECK: %{{.*}} = fir.call @__nv_float_as_int(%{{.*}}) proc_attrs fastmath : (f32) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_float_as_int(%{{.*}}) proc_attrs fastmath : (f32) -> i32 attributes(global) subroutine test_double2loint() integer :: res @@ -314,7 +314,7 @@ attributes(global) subroutine test_double2loint() end subroutine ! CHECK-LABEL: _QPtest_double2loint -! CHECK: %{{.*}} = fir.call @__nv_double2loint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2loint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 attributes(global) subroutine test_double2hiint() integer :: res @@ -323,7 +323,7 @@ attributes(global) subroutine test_double2hiint() end subroutine ! CHECK-LABEL: _QPtest_double2hiint -! CHECK: %{{.*}} = fir.call @__nv_double2hiint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 +! CHECK: %{{.*}} = fir.call @__nv_double2hiint(%{{.*}}) proc_attrs fastmath : (f64) -> i32 attributes(global) subroutine test_hiloint2double() double precision :: res @@ -332,4 +332,4 @@ attributes(global) subroutine test_hiloint2double() end subroutine ! CHECK-LABEL: _QPtest_hiloint2double -! CHECK: %{{.*}} = fir.call @__nv_hiloint2double(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> f64 +! CHECK: %{{.*}} = fir.call @__nv_hiloint2double(%{{.*}}, %{{.*}}) proc_attrs fastmath : (i32, i32) -> f64 diff --git a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 index 0f00e06dfdb1a..eb72b9b9197b9 100644 --- a/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 +++ b/flang/test/Lower/OpenMP/threadprivate-default-clause.f90 @@ -12,7 +12,7 @@ !CHECK: omp.parallel { !CHECK: %[[A_TP:.*]] = omp.threadprivate %[[A_DECL]]#0 : !fir.ref -> !fir.ref !CHECK: %[[A_TP_DECL:.*]]:2 = hlfir.declare %[[A_TP]] {uniq_name = "_QFsub1Ea"} : (!fir.ref) -> (!fir.ref, !fir.ref) -!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 +!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 !CHECK: hlfir.assign %[[TID]] to %[[A_TP_DECL]]#0 : i32, !fir.ref !CHECK: omp.terminator !CHECK: } @@ -43,7 +43,7 @@ subroutine sub1() !CHECK: %[[A_TP_ADDR:.*]] = fir.coordinate_of %[[BLK_TP]], %c0_1 : (!fir.ref>, index) -> !fir.ref !CHECK: %[[A_TP_ADDR_CVT:.*]] = fir.convert %[[A_TP_ADDR]] : (!fir.ref) -> !fir.ref !CHECK: %[[A_TP_DECL:.*]]:2 = hlfir.declare %[[A_TP_ADDR_CVT]] storage(%[[BLK_TP]][0]) {uniq_name = "_QFsub2Ea"} : (!fir.ref, !fir.ref>) -> (!fir.ref, !fir.ref) -!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 +!CHECK: %[[TID:.*]] = fir.call @omp_get_thread_num() proc_attrs fastmath : () -> i32 !CHECK: hlfir.assign %[[TID]] to %[[A_TP_DECL]]#0 : i32, !fir.ref !CHECK: omp.terminator !CHECK: } From 6b7b8d38d47f091d953080a354692cf4f70bfd17 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 9 Jul 2026 12:46:30 -0700 Subject: [PATCH 009/125] [SampleProfile] Replace std::set with SmallVector in SortedCallTargetSet (NFC) (#208509) This patch replaces std::set with SmallVector and llvm::sort in SortedCallTargetSet and sortCallTargets. Since the keys in CallTargetMap are already guaranteed to be unique, using std::set for sorting allocates unnecessary tree nodes on the heap. This patch also removes unnecessary const from return-by-value types to enable move semantics. Assisted-by: Antigravity --- llvm/include/llvm/ProfileData/SampleProf.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h index e4f467c45c66a..b9eabcd661549 100644 --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -386,7 +385,7 @@ class SampleRecord { } }; - using SortedCallTargetSet = std::set; + using SortedCallTargetSet = SmallVector; using CallTargetMap = DenseMap; SampleRecord() = default; @@ -443,7 +442,7 @@ class SampleRecord { uint64_t getSamples() const { return NumSamples; } const CallTargetMap &getCallTargets() const { return CallTargets; } - const SortedCallTargetSet getSortedCallTargets() const { + SortedCallTargetSet getSortedCallTargets() const { return sortCallTargets(CallTargets); } @@ -455,12 +454,9 @@ class SampleRecord { } /// Sort call targets in descending order of call frequency. - static const SortedCallTargetSet - sortCallTargets(const CallTargetMap &Targets) { - SortedCallTargetSet SortedTargets; - for (const auto &[Target, Frequency] : Targets) { - SortedTargets.emplace(Target, Frequency); - } + static SortedCallTargetSet sortCallTargets(const CallTargetMap &Targets) { + auto SortedTargets = llvm::to_vector_of(Targets); + llvm::sort(SortedTargets, CallTargetComparator()); return SortedTargets; } From 5815dfe402a8a6b1e39edb8524fbe4d0eb885feb Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Thu, 9 Jul 2026 21:48:40 +0200 Subject: [PATCH 010/125] [X86] promote f16 `frexp` (#208530) follow-up to https://github.com/llvm/llvm-project/pull/208462 Using the libcall reduces code size, gives identical output for the full f16 range, and is apparently quite a bit faster ``` direct f16: 2.067486000 s for 1000 full-range iterations via f32: 0.714443000 s for 1000 full-range iterations ``` --- llvm/lib/Target/X86/X86ISelLowering.cpp | 1 + .../test/CodeGen/X86/float-to-arbitrary-fp.ll | 531 ++++++++---------- llvm/test/CodeGen/X86/llvm.frexp.ll | 82 +-- 3 files changed, 256 insertions(+), 358 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cfbaca6059c42..46edb6c001955 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -645,6 +645,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM, setOperationAction(ISD::FROUNDEVEN, VT, Action); setOperationAction(ISD::FTRUNC, VT, Action); setOperationAction(ISD::FLDEXP, VT, Action); + setOperationAction(ISD::FFREXP, VT, Action); setOperationAction(ISD::FSINCOSPI, VT, Action); }; diff --git a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll index 1cdccaf110d30..8076f0a11762c 100644 --- a/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll +++ b/llvm/test/CodeGen/X86/float-to-arbitrary-fp.ll @@ -1858,215 +1858,182 @@ define <2 x i8> @to_f8e4m3fn_v2f16(<2 x half> %x) { ; CHECK-NEXT: .cfi_def_cfa_offset 48 ; CHECK-NEXT: pushq %rbx ; CHECK-NEXT: .cfi_def_cfa_offset 56 -; CHECK-NEXT: subq $72, %rsp -; CHECK-NEXT: .cfi_def_cfa_offset 128 +; CHECK-NEXT: subq $88, %rsp +; CHECK-NEXT: .cfi_def_cfa_offset 144 ; CHECK-NEXT: .cfi_offset %rbx, -56 ; CHECK-NEXT: .cfi_offset %r12, -48 ; CHECK-NEXT: .cfi_offset %r13, -40 ; CHECK-NEXT: .cfi_offset %r14, -32 ; CHECK-NEXT: .cfi_offset %r15, -24 ; CHECK-NEXT: .cfi_offset %rbp, -16 -; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: movl $2, %ebx +; CHECK-NEXT: movl $2, %ebp +; CHECK-NEXT: subl %eax, %ebp +; CHECK-NEXT: cmpw $15, %bp +; CHECK-NEXT: movl $15, %eax +; CHECK-NEXT: cmovael %eax, %ebp +; CHECK-NEXT: cmpw $1, %bp +; CHECK-NEXT: movl %ebp, %r14d +; CHECK-NEXT: adcl $-1, %r14d ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %r12d -; CHECK-NEXT: movl %r12d, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 +; CHECK-NEXT: pextrw $0, %xmm0, %r13d +; CHECK-NEXT: movl %r13d, %eax +; CHECK-NEXT: andl $1023, %eax # imm = 0x3FF +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: leal 1024(%rax), %edi +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: movl %r14d, %ecx +; CHECK-NEXT: shrl %cl, %eax +; CHECK-NEXT: movl $1, %r15d +; CHECK-NEXT: movl $1, %edx +; CHECK-NEXT: shll %cl, %edx +; CHECK-NEXT: decl %edx +; CHECK-NEXT: xorl %esi, %esi +; CHECK-NEXT: movl %edi, %r14d +; CHECK-NEXT: testw %dx, %r14w +; CHECK-NEXT: setne %sil +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %r14d +; CHECK-NEXT: movl %r14d, %r12d +; CHECK-NEXT: andl $1, %r12d +; CHECK-NEXT: orl %esi, %r12d +; CHECK-NEXT: andl %eax, %r12d +; CHECK-NEXT: xorl %eax, %eax +; CHECK-NEXT: cmpw $1, %bp ; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %r15d -; CHECK-NEXT: movl %r15d, %ecx -; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %r15d, %r12d -; CHECK-NEXT: cmovael %ecx, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %edx -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 ; CHECK-NEXT: psrld $16, %xmm0 ; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill -; CHECK-NEXT: cmovael %eax, %edx -; CHECK-NEXT: addl $-14, %edx -; CHECK-NEXT: andl $33791, %r12d # imm = 0x83FF -; CHECK-NEXT: orl $14336, %r12d # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400 -; CHECK-NEXT: movzwl %cx, %eax -; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400 -; CHECK-NEXT: cmovbel %ecx, %edx -; CHECK-NEXT: movq %rdx, %r14 -; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: cmovbel %r15d, %r12d +; CHECK-NEXT: cmovbl %eax, %r12d ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax +; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill +; CHECK-NEXT: subl %eax, %ebx +; CHECK-NEXT: cmpw $15, %bx +; CHECK-NEXT: movl $15, %eax +; CHECK-NEXT: cmovael %eax, %ebx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl %ebx, %ebp +; CHECK-NEXT: adcl $-1, %ebp ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %ebp -; CHECK-NEXT: movl %ebp, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 -; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %ebx -; CHECK-NEXT: movl %ebx, %r9d -; CHECK-NEXT: andl $32767, %r9d # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400 -; CHECK-NEXT: cmovael %ebx, %ebp -; CHECK-NEXT: cmovael %r9d, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %esi -; CHECK-NEXT: cmpl $1024, %r9d # imm = 0x400 -; CHECK-NEXT: cmovael %eax, %esi -; CHECK-NEXT: movl $2, %eax -; CHECK-NEXT: movl $2, %edx -; CHECK-NEXT: subl %r14d, %edx -; CHECK-NEXT: cmpw $15, %dx -; CHECK-NEXT: movl $15, %r13d -; CHECK-NEXT: cmovael %r13d, %edx -; CHECK-NEXT: cmpw $1, %dx -; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %r12d, %r10d -; CHECK-NEXT: andl $1023, %r10d # imm = 0x3FF -; CHECK-NEXT: leal 1024(%r10), %edi -; CHECK-NEXT: movl %edi, %r14d -; CHECK-NEXT: shrl %cl, %r14d -; CHECK-NEXT: movl $1, %r8d -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r8d -; CHECK-NEXT: decl %r8d -; CHECK-NEXT: xorl %r11d, %r11d -; CHECK-NEXT: testw %r8w, %di -; CHECK-NEXT: setne %r11b -; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: shrl %cl, %edi -; CHECK-NEXT: movl %edi, %r8d -; CHECK-NEXT: andl $1, %r8d -; CHECK-NEXT: orl %r11d, %r8d -; CHECK-NEXT: movl $1, %r11d -; CHECK-NEXT: andl %r14d, %r8d -; CHECK-NEXT: cmpw $1, %dx -; CHECK-NEXT: movl $0, %edx -; CHECK-NEXT: cmovbl %edx, %r8d -; CHECK-NEXT: addl $-14, %esi -; CHECK-NEXT: andl $33791, %ebp # imm = 0x83FF -; CHECK-NEXT: orl $14336, %ebp # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %r9d # imm = 0x8400 -; CHECK-NEXT: movzwl %r9w, %ecx -; CHECK-NEXT: cmpl $33792, %ecx # imm = 0x8400 -; CHECK-NEXT: cmovbel %edx, %esi -; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: cmovbel %ebx, %ebp -; CHECK-NEXT: subl %esi, %eax -; CHECK-NEXT: cmpw $15, %ax -; CHECK-NEXT: cmovael %r13d, %eax -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %ebp, %edx +; CHECK-NEXT: pextrw $0, %xmm0, %eax +; CHECK-NEXT: movl %eax, %edx ; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF -; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) # 8-byte Spill -; CHECK-NEXT: leal 1024(%rdx), %r13d -; CHECK-NEXT: movl %r13d, %edx -; CHECK-NEXT: shrl %cl, %edx -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r11d -; CHECK-NEXT: decl %r11d -; CHECK-NEXT: xorl %r9d, %r9d -; CHECK-NEXT: testw %r11w, %r13w -; CHECK-NEXT: setne %r9b -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: shrl %cl, %r13d -; CHECK-NEXT: movl %r13d, %r14d -; CHECK-NEXT: andl $1, %r14d -; CHECK-NEXT: orl %r9d, %r14d -; CHECK-NEXT: andl %edx, %r14d -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl $0, %ecx -; CHECK-NEXT: cmovbl %ecx, %r14d -; CHECK-NEXT: addl %edi, %r8d -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $8, %r8w -; CHECK-NEXT: cmovgel %ecx, %r8d -; CHECK-NEXT: movl $0, %esi -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %r15d -; CHECK-NEXT: andl $128, %r15d -; CHECK-NEXT: leal (%r15,%rax,8), %eax -; CHECK-NEXT: orl %r8d, %eax -; CHECK-NEXT: shrl $7, %r10d -; CHECK-NEXT: movl %r10d, %ecx +; CHECK-NEXT: leal 1024(%rdx), %esi +; CHECK-NEXT: movl %esi, %edi +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %edi +; CHECK-NEXT: shll %cl, %r15d +; CHECK-NEXT: decl %r15d +; CHECK-NEXT: xorl %r8d, %r8d +; CHECK-NEXT: testw %r15w, %si +; CHECK-NEXT: setne %r8b +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: shrl %cl, %esi +; CHECK-NEXT: movl %esi, %ecx ; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: testb $63, %r12b -; CHECK-NEXT: setne %dl -; CHECK-NEXT: orl %ecx, %edx -; CHECK-NEXT: shrl $6, %r12d -; CHECK-NEXT: andl %edx, %r12d -; CHECK-NEXT: addl %r10d, %r12d -; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: orl %r8d, %ecx +; CHECK-NEXT: andl %edi, %ecx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl $0, %r8d +; CHECK-NEXT: cmovbl %r8d, %ecx +; CHECK-NEXT: addl %r14d, %r12d +; CHECK-NEXT: xorl %edi, %edi ; CHECK-NEXT: cmpw $8, %r12w -; CHECK-NEXT: cmovgel %esi, %r12d -; CHECK-NEXT: setge %cl -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload -; CHECK-NEXT: leal (%rsi,%rcx), %edx -; CHECK-NEXT: leal 48(,%rdx,8), %edx -; CHECK-NEXT: orl %r15d, %r12d -; CHECK-NEXT: orl %edx, %r12d -; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx -; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %r12d -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %r12d, %r15d -; CHECK-NEXT: cmovpl %r12d, %r15d -; CHECK-NEXT: movl $127, %r12d -; CHECK-NEXT: cmovpl %r12d, %r15d -; CHECK-NEXT: movzbl %r15b, %r15d -; CHECK-NEXT: addl %r13d, %r14d -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $8, %r14w -; CHECK-NEXT: movl $0, %edi -; CHECK-NEXT: cmovgel %edi, %r14d -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %ebx -; CHECK-NEXT: andl $128, %ebx -; CHECK-NEXT: leal (%rbx,%rax,8), %eax -; CHECK-NEXT: orl %r14d, %eax -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rdx # 8-byte Reload +; CHECK-NEXT: cmovgel %r8d, %r12d +; CHECK-NEXT: movl $0, %r11d +; CHECK-NEXT: setge %dil +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm0, %r8d +; CHECK-NEXT: shrl $8, %r8d +; CHECK-NEXT: andl $128, %r8d +; CHECK-NEXT: leal (%r8,%rdi,8), %edi +; CHECK-NEXT: orl %r12d, %edi +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; CHECK-NEXT: shrl $7, %r10d +; CHECK-NEXT: movl %r10d, %r9d +; CHECK-NEXT: movq %r10, %rbx +; CHECK-NEXT: andl $1, %r9d +; CHECK-NEXT: xorl %r10d, %r10d +; CHECK-NEXT: testb $63, %r13b +; CHECK-NEXT: setne %r10b +; CHECK-NEXT: orl %r9d, %r10d +; CHECK-NEXT: shrl $6, %r13d +; CHECK-NEXT: andl %r10d, %r13d +; CHECK-NEXT: addl %ebx, %r13d +; CHECK-NEXT: xorl %r9d, %r9d +; CHECK-NEXT: cmpw $8, %r13w +; CHECK-NEXT: cmovgel %r11d, %r13d +; CHECK-NEXT: setge %r9b +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rbx # 8-byte Reload +; CHECK-NEXT: leal (%rbx,%r9), %r10d +; CHECK-NEXT: leal 48(,%r10,8), %r10d +; CHECK-NEXT: orl %r8d, %r13d +; CHECK-NEXT: orl %r10d, %r13d +; CHECK-NEXT: leal 6(%rbx,%r9), %r9d +; CHECK-NEXT: testw %r9w, %r9w +; CHECK-NEXT: cmovlel %edi, %r13d +; CHECK-NEXT: pxor %xmm0, %xmm0 +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload +; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %r13d, %r8d +; CHECK-NEXT: cmovpl %r13d, %r8d +; CHECK-NEXT: movl $127, %edi +; CHECK-NEXT: cmovpl %edi, %r8d +; CHECK-NEXT: movzbl %r8b, %r8d +; CHECK-NEXT: addl %esi, %ecx +; CHECK-NEXT: xorl %r9d, %r9d +; CHECK-NEXT: cmpw $8, %cx +; CHECK-NEXT: cmovgel %r11d, %ecx +; CHECK-NEXT: setge %r9b +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm1, %esi +; CHECK-NEXT: shrl $8, %esi +; CHECK-NEXT: andl $128, %esi +; CHECK-NEXT: leal (%rsi,%r9,8), %r9d +; CHECK-NEXT: orl %ecx, %r9d ; CHECK-NEXT: shrl $7, %edx ; CHECK-NEXT: movl %edx, %ecx -; CHECK-NEXT: movq %rdx, %rsi ; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: testb $63, %bpl -; CHECK-NEXT: setne %dl -; CHECK-NEXT: orl %ecx, %edx -; CHECK-NEXT: shrl $6, %ebp -; CHECK-NEXT: andl %edx, %ebp -; CHECK-NEXT: addl %esi, %ebp +; CHECK-NEXT: xorl %r10d, %r10d +; CHECK-NEXT: testb $63, %al +; CHECK-NEXT: setne %r10b +; CHECK-NEXT: orl %ecx, %r10d +; CHECK-NEXT: shrl $6, %eax +; CHECK-NEXT: andl %r10d, %eax +; CHECK-NEXT: addl %edx, %eax ; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpw $8, %bp -; CHECK-NEXT: cmovgel %edi, %ebp +; CHECK-NEXT: cmpw $8, %ax +; CHECK-NEXT: cmovgel %r11d, %eax ; CHECK-NEXT: setge %cl -; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %rsi # 8-byte Reload -; CHECK-NEXT: leal (%rsi,%rcx), %edx +; CHECK-NEXT: movq {{[-0-9]+}}(%r{{[sb]}}p), %r10 # 8-byte Reload +; CHECK-NEXT: leal (%r10,%rcx), %edx ; CHECK-NEXT: leal 48(,%rdx,8), %edx -; CHECK-NEXT: orl %ebx, %ebp -; CHECK-NEXT: orl %edx, %ebp -; CHECK-NEXT: leal 6(%rsi,%rcx), %ecx +; CHECK-NEXT: orl %esi, %eax +; CHECK-NEXT: orl %edx, %eax +; CHECK-NEXT: leal 6(%r10,%rcx), %ecx ; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %ebp -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %ebp, %ebx -; CHECK-NEXT: cmovpl %ebp, %ebx -; CHECK-NEXT: cmovpl %r12d, %ebx -; CHECK-NEXT: shll $8, %ebx -; CHECK-NEXT: orl %r15d, %ebx -; CHECK-NEXT: movd %ebx, %xmm0 -; CHECK-NEXT: addq $72, %rsp +; CHECK-NEXT: cmovlel %r9d, %eax +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload +; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %eax, %esi +; CHECK-NEXT: cmovpl %eax, %esi +; CHECK-NEXT: cmovpl %edi, %esi +; CHECK-NEXT: shll $8, %esi +; CHECK-NEXT: orl %r8d, %esi +; CHECK-NEXT: movd %esi, %xmm0 +; CHECK-NEXT: addq $88, %rsp ; CHECK-NEXT: .cfi_def_cfa_offset 56 ; CHECK-NEXT: popq %rbx ; CHECK-NEXT: .cfi_def_cfa_offset 48 @@ -2102,121 +2069,105 @@ define i8 @to_f8e5m2_from_f16(half %x) { ; CHECK-NEXT: .cfi_offset %rbx, -32 ; CHECK-NEXT: .cfi_offset %r14, -24 ; CHECK-NEXT: .cfi_offset %rbp, -16 -; CHECK-NEXT: movaps %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill +; CHECK-NEXT: movdqa %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill ; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill +; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; CHECK-NEXT: callq frexpf@PLT +; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r14d +; CHECK-NEXT: movl $-5, %eax +; CHECK-NEXT: subl %r14d, %eax +; CHECK-NEXT: cmpw $15, %ax +; CHECK-NEXT: movl $15, %ebx +; CHECK-NEXT: cmovbl %eax, %ebx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: movl %ebx, %ebp +; CHECK-NEXT: adcl $-1, %ebp ; CHECK-NEXT: callq __truncsfhf2@PLT -; CHECK-NEXT: pextrw $0, %xmm0, %edx -; CHECK-NEXT: movl %edx, %eax -; CHECK-NEXT: andl $31744, %eax # imm = 0x7C00 -; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: pextrw $0, %xmm0, %ebx -; CHECK-NEXT: movl %ebx, %ecx -; CHECK-NEXT: andl $32767, %ecx # imm = 0x7FFF -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %ebx, %edx -; CHECK-NEXT: cmovael %ecx, %eax -; CHECK-NEXT: shrl $10, %eax -; CHECK-NEXT: leal -12(%rax), %esi -; CHECK-NEXT: cmpl $1024, %ecx # imm = 0x400 -; CHECK-NEXT: cmovael %eax, %esi -; CHECK-NEXT: addl $-14, %esi -; CHECK-NEXT: andl $33791, %edx # imm = 0x83FF -; CHECK-NEXT: orl $14336, %edx # imm = 0x3800 -; CHECK-NEXT: addl $-31744, %ecx # imm = 0x8400 -; CHECK-NEXT: movzwl %cx, %eax -; CHECK-NEXT: xorl %edi, %edi -; CHECK-NEXT: cmpl $33792, %eax # imm = 0x8400 -; CHECK-NEXT: cmovbel %edi, %esi -; CHECK-NEXT: cmovbel %ebx, %edx -; CHECK-NEXT: movl $-5, %ecx -; CHECK-NEXT: subl %esi, %ecx -; CHECK-NEXT: cmpw $15, %cx -; CHECK-NEXT: movl $15, %eax -; CHECK-NEXT: cmovbl %ecx, %eax -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: adcl $-1, %ecx -; CHECK-NEXT: movl %edx, %r8d -; CHECK-NEXT: andl $1023, %r8d # imm = 0x3FF -; CHECK-NEXT: leal 1024(%r8), %r9d -; CHECK-NEXT: movl %r9d, %r10d -; CHECK-NEXT: shrl %cl, %r10d -; CHECK-NEXT: movl $1, %r11d -; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx -; CHECK-NEXT: shll %cl, %r11d -; CHECK-NEXT: decl %r11d -; CHECK-NEXT: xorl %ebp, %ebp -; CHECK-NEXT: testw %r11w, %r9w -; CHECK-NEXT: setne %bpl -; CHECK-NEXT: movl %eax, %ecx -; CHECK-NEXT: shrl %cl, %r9d -; CHECK-NEXT: movl %r9d, %ecx -; CHECK-NEXT: andl $1, %ecx -; CHECK-NEXT: orl %ebp, %ecx -; CHECK-NEXT: andl %r10d, %ecx -; CHECK-NEXT: cmpw $1, %ax -; CHECK-NEXT: cmovbl %edi, %ecx -; CHECK-NEXT: addl %r9d, %ecx -; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpw $4, %cx -; CHECK-NEXT: cmovgel %edi, %ecx -; CHECK-NEXT: setge %al -; CHECK-NEXT: shrl $8, %ebx -; CHECK-NEXT: andl $128, %ebx -; CHECK-NEXT: leal (%rbx,%rax,4), %eax -; CHECK-NEXT: orl %ecx, %eax -; CHECK-NEXT: shrl $8, %r8d -; CHECK-NEXT: movl %r8d, %ecx -; CHECK-NEXT: andl $1, %ecx +; CHECK-NEXT: pextrw $0, %xmm0, %eax +; CHECK-NEXT: movl %eax, %edx +; CHECK-NEXT: andl $1023, %edx # imm = 0x3FF +; CHECK-NEXT: leal 1024(%rdx), %esi +; CHECK-NEXT: movl %esi, %edi +; CHECK-NEXT: movl %ebp, %ecx +; CHECK-NEXT: shrl %cl, %edi +; CHECK-NEXT: movl $1, %r8d +; CHECK-NEXT: shll %cl, %r8d +; CHECK-NEXT: decl %r8d ; CHECK-NEXT: xorl %r9d, %r9d -; CHECK-NEXT: testb $127, %dl +; CHECK-NEXT: testw %r8w, %si ; CHECK-NEXT: setne %r9b -; CHECK-NEXT: orl %ecx, %r9d -; CHECK-NEXT: shrl $7, %edx -; CHECK-NEXT: andl %r9d, %edx -; CHECK-NEXT: addl %r8d, %edx +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: shrl %cl, %esi +; CHECK-NEXT: movl %esi, %r8d +; CHECK-NEXT: andl $1, %r8d +; CHECK-NEXT: orl %r9d, %r8d +; CHECK-NEXT: andl %edi, %r8d ; CHECK-NEXT: xorl %ecx, %ecx -; CHECK-NEXT: cmpw $4, %dx -; CHECK-NEXT: cmovgel %edi, %edx -; CHECK-NEXT: setge %cl -; CHECK-NEXT: leal (%rsi,%rcx), %edi -; CHECK-NEXT: leal 56(,%rdi,4), %edi -; CHECK-NEXT: movl %ebx, %ebp -; CHECK-NEXT: orl %edx, %ebp -; CHECK-NEXT: orl %edi, %ebp -; CHECK-NEXT: leal 14(%rsi,%rcx), %ecx -; CHECK-NEXT: testw %cx, %cx -; CHECK-NEXT: cmovlel %eax, %ebp -; CHECK-NEXT: cmpw $4, %dx +; CHECK-NEXT: cmpw $1, %bx +; CHECK-NEXT: cmovbl %ecx, %r8d +; CHECK-NEXT: addl %esi, %r8d +; CHECK-NEXT: xorl %esi, %esi +; CHECK-NEXT: cmpw $4, %r8w +; CHECK-NEXT: cmovgel %ecx, %r8d +; CHECK-NEXT: setge %sil +; CHECK-NEXT: movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload +; CHECK-NEXT: pextrw $0, %xmm1, %ebx +; CHECK-NEXT: shrl $8, %ebx +; CHECK-NEXT: andl $128, %ebx +; CHECK-NEXT: leal (%rbx,%rsi,4), %esi +; CHECK-NEXT: orl %r8d, %esi +; CHECK-NEXT: shrl $8, %edx +; CHECK-NEXT: movl %edx, %edi +; CHECK-NEXT: andl $1, %edi +; CHECK-NEXT: xorl %r8d, %r8d +; CHECK-NEXT: testb $127, %al +; CHECK-NEXT: setne %r8b +; CHECK-NEXT: orl %edi, %r8d +; CHECK-NEXT: shrl $7, %eax +; CHECK-NEXT: andl %r8d, %eax +; CHECK-NEXT: addl %edx, %eax +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: cmpw $4, %ax +; CHECK-NEXT: cmovgel %ecx, %eax +; CHECK-NEXT: setge %dl +; CHECK-NEXT: leal (%r14,%rdx), %ecx +; CHECK-NEXT: leal 56(,%rcx,4), %edi +; CHECK-NEXT: movl %ebx, %ecx +; CHECK-NEXT: orl %eax, %ecx +; CHECK-NEXT: orl %edi, %ecx +; CHECK-NEXT: leal 14(%r14,%rdx), %edx +; CHECK-NEXT: testw %dx, %dx +; CHECK-NEXT: cmovlel %esi, %ecx +; CHECK-NEXT: cmpw $4, %ax ; CHECK-NEXT: setge %al -; CHECK-NEXT: cmpw $30, %cx -; CHECK-NEXT: sete %dl -; CHECK-NEXT: andb %al, %dl -; CHECK-NEXT: cmpw $31, %cx +; CHECK-NEXT: cmpw $30, %dx +; CHECK-NEXT: sete %sil +; CHECK-NEXT: andb %al, %sil +; CHECK-NEXT: cmpw $31, %dx ; CHECK-NEXT: setge %al -; CHECK-NEXT: orb %dl, %al -; CHECK-NEXT: leal 124(%rbx), %r14d +; CHECK-NEXT: orb %sil, %al +; CHECK-NEXT: leal 124(%rbx), %ebp ; CHECK-NEXT: testb %al, %al -; CHECK-NEXT: cmovnel %r14d, %ebp -; CHECK-NEXT: callq __extendhfsf2@PLT -; CHECK-NEXT: movd %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Folded Spill -; CHECK-NEXT: xorps %xmm1, %xmm1 -; CHECK-NEXT: ucomiss %xmm1, %xmm0 -; CHECK-NEXT: cmovnel %ebp, %ebx -; CHECK-NEXT: cmovpl %ebp, %ebx -; CHECK-NEXT: movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload -; CHECK-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; CHECK-NEXT: cmovnel %ebp, %ecx +; CHECK-NEXT: xorps %xmm2, %xmm2 +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload +; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero +; CHECK-NEXT: ucomiss %xmm2, %xmm0 +; CHECK-NEXT: cmovnel %ecx, %ebx +; CHECK-NEXT: cmovpl %ecx, %ebx +; CHECK-NEXT: movdqa %xmm1, %xmm0 +; CHECK-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; CHECK-NEXT: callq __extendhfsf2@PLT ; CHECK-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 -; CHECK-NEXT: cmovnel %ebx, %r14d -; CHECK-NEXT: cmovpl %ebx, %r14d -; CHECK-NEXT: xorps %xmm0, %xmm0 -; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload -; CHECK-NEXT: # xmm1 = mem[0],zero,zero,zero -; CHECK-NEXT: ucomiss %xmm0, %xmm1 +; CHECK-NEXT: cmovnel %ebx, %ebp +; CHECK-NEXT: cmovpl %ebx, %ebp +; CHECK-NEXT: movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload +; CHECK-NEXT: # xmm0 = mem[0],zero,zero,zero +; CHECK-NEXT: pxor %xmm1, %xmm1 +; CHECK-NEXT: ucomiss %xmm1, %xmm0 ; CHECK-NEXT: movl $126, %eax -; CHECK-NEXT: cmovnpl %r14d, %eax +; CHECK-NEXT: cmovnpl %ebp, %eax ; CHECK-NEXT: # kill: def $al killed $al killed $eax ; CHECK-NEXT: addq $32, %rsp ; CHECK-NEXT: .cfi_def_cfa_offset 32 diff --git a/llvm/test/CodeGen/X86/llvm.frexp.ll b/llvm/test/CodeGen/X86/llvm.frexp.ll index d14d737a5ca29..3410fd5169c9a 100644 --- a/llvm/test/CodeGen/X86/llvm.frexp.ll +++ b/llvm/test/CodeGen/X86/llvm.frexp.ll @@ -5,36 +5,13 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT ; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: movl %ecx, %eax -; X64-NEXT: andl $31744, %eax # imm = 0x7C00 -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %edx -; X64-NEXT: movl %edx, %esi -; X64-NEXT: andl $32767, %esi # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %esi # imm = 0x400 -; X64-NEXT: cmovael %edx, %ecx -; X64-NEXT: cmovael %esi, %eax -; X64-NEXT: shrl $10, %eax -; X64-NEXT: leal -12(%rax), %edi -; X64-NEXT: cmpl $1024, %esi # imm = 0x400 -; X64-NEXT: cmovael %eax, %edi -; X64-NEXT: addl $-14, %edi -; X64-NEXT: andl $33791, %ecx # imm = 0x83FF -; X64-NEXT: orl $14336, %ecx # imm = 0x3800 -; X64-NEXT: addl $-31744, %esi # imm = 0x8400 -; X64-NEXT: movzwl %si, %esi -; X64-NEXT: xorl %eax, %eax -; X64-NEXT: cmpl $33792, %esi # imm = 0x8400 -; X64-NEXT: cmoval %edi, %eax -; X64-NEXT: cmovbel %edx, %ecx -; X64-NEXT: pinsrw $0, %ecx, %xmm0 -; X64-NEXT: addq $24, %rsp +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32: @@ -64,26 +41,12 @@ define { half, i32 } @test_frexp_f16_i32(half %a) nounwind { define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32_only_use_fract: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT ; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %eax -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: movl %ecx, %edx -; X64-NEXT: andl $32767, %edx # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %edx # imm = 0x400 -; X64-NEXT: cmovael %ecx, %eax -; X64-NEXT: andl $33791, %eax # imm = 0x83FF -; X64-NEXT: orl $14336, %eax # imm = 0x3800 -; X64-NEXT: addl $-31744, %edx # imm = 0x8400 -; X64-NEXT: movzwl %dx, %edx -; X64-NEXT: cmpl $33792, %edx # imm = 0x8400 -; X64-NEXT: cmovbel %ecx, %eax -; X64-NEXT: pinsrw $0, %eax, %xmm0 -; X64-NEXT: addq $24, %rsp +; X64-NEXT: popq %rax ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32_only_use_fract: @@ -110,29 +73,12 @@ define half @test_frexp_f16_i32_only_use_fract(half %a) nounwind { define i32 @test_frexp_f16_i32_only_use_exp(half %a) nounwind { ; X64-LABEL: test_frexp_f16_i32_only_use_exp: ; X64: # %bb.0: -; X64-NEXT: subq $24, %rsp -; X64-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill +; X64-NEXT: pushq %rax ; X64-NEXT: callq __extendhfsf2@PLT -; X64-NEXT: mulss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 -; X64-NEXT: callq __truncsfhf2@PLT -; X64-NEXT: pextrw $0, %xmm0, %eax -; X64-NEXT: andl $31744, %eax # imm = 0x7C00 -; X64-NEXT: movdqa (%rsp), %xmm0 # 16-byte Reload -; X64-NEXT: pextrw $0, %xmm0, %ecx -; X64-NEXT: andl $32767, %ecx # imm = 0x7FFF -; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 -; X64-NEXT: cmovael %ecx, %eax -; X64-NEXT: shrl $10, %eax -; X64-NEXT: leal -12(%rax), %edx -; X64-NEXT: cmpl $1024, %ecx # imm = 0x400 -; X64-NEXT: cmovael %eax, %edx -; X64-NEXT: addl $-14, %edx -; X64-NEXT: addl $-31744, %ecx # imm = 0x8400 -; X64-NEXT: movzwl %cx, %ecx -; X64-NEXT: xorl %eax, %eax -; X64-NEXT: cmpl $33792, %ecx # imm = 0x8400 -; X64-NEXT: cmoval %edx, %eax -; X64-NEXT: addq $24, %rsp +; X64-NEXT: leaq {{[0-9]+}}(%rsp), %rdi +; X64-NEXT: callq frexpf@PLT +; X64-NEXT: movl {{[0-9]+}}(%rsp), %eax +; X64-NEXT: popq %rcx ; X64-NEXT: retq ; ; WIN32-LABEL: test_frexp_f16_i32_only_use_exp: From ed6097402fcfdbd3965471de70304de90f72cea9 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 9 Jul 2026 20:56:03 +0100 Subject: [PATCH 011/125] [SCEV] Add more tests for reasoning about min/max expressions (NFC) (#208535) --- .../minmax-decomposition-guards.ll | 627 ++++++++++++++++++ .../early-exit-minmax-trip-count.ll | 330 +++++++++ .../early-exit-umin-trip-count.ll | 103 --- 3 files changed, 957 insertions(+), 103 deletions(-) create mode 100644 llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll create mode 100644 llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll delete mode 100644 llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll diff --git a/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll b/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll new file mode 100644 index 0000000000000..35c7790347dc7 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/minmax-decomposition-guards.ll @@ -0,0 +1,627 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -disable-output -passes='print' -scalar-evolution-classify-expressions=0 %s 2>&1 | FileCheck %s + +declare void @use(i64) + +; all_of max: umax start value, every operand bounded by %bound. +define void @umax_start(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start' +; CHECK-NEXT: Determining loop execution counts for: @umax_start +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_ne_pred(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_ne_pred' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_ne_pred +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ne i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'umax_start_3op' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1 umax %x2)) + (%x0 umax %x1 umax %x2 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1 umax %x2)) + (%x0 umax %x1 umax %x2 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp ule i64 %x2, %bound + call void @llvm.assume(i1 %pre.x2) + %max01 = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + %start = call i64 @llvm.umax.i64(i64 %max01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, guards/condition written with operands swapped (%bound uge %x). +define void @umax_start_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp uge i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp uge i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ugt i64 %bound, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, signed. +define void @smax_start(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start' +; CHECK-NEXT: Determining loop execution counts for: @smax_start +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smax_start_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start_ne' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp ne i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smax_start_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'smax_start_3op' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1 smax %x2)) + (%x0 smax %x1 smax %x2 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1 smax %x2)) + (%x0 smax %x1 smax %x2 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp sle i64 %x2, %bound + call void @llvm.assume(i1 %pre.x2) + %max01 = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + %start = call i64 @llvm.smax.i64(i64 %max01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of max, signed, guards/condition written with operands swapped +; (%bound sge %x). +define void @smax_start_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smax_start_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @smax_start_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smax %x1)) + (%x0 smax %x1 smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sge i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sge i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %start = call i64 @llvm.smax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp sgt i64 %bound, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min: umin limit, every operand bounded below by %bound (the start). +define void @umin_limit(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_ne' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 umin %x1)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 umin %x1)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ne i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'umin_limit_3op' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1 umin %x2) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1 umin %x2) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ule i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp ule i64 %bound, %x2 + call void @llvm.assume(i1 %pre.x2) + %min01 = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + %lim = call i64 @llvm.umin.i64(i64 %min01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min, guards/condition written with operands swapped (%x uge %bound). +define void @umin_limit_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp uge i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp uge i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ugt i64 %lim, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +; all_of min, signed: smin limit, every operand bounded below by %bound. +define void @smin_limit(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_ne(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit_ne' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_ne +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 smin %x1)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 smin %x1)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ne i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp ne i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp ne i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_3op(i64 %x0, i64 %x1, i64 %x2, i64 %bound) { +; CHECK-LABEL: 'smin_limit_3op' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_3op +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1 smin %x2) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1 smin %x2) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sle i64 %bound, %x1 + call void @llvm.assume(i1 %pre.x1) + %pre.x2 = icmp sle i64 %bound, %x2 + call void @llvm.assume(i1 %pre.x2) + %min01 = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + %lim = call i64 @llvm.smin.i64(i64 %min01, i64 %x2) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_limit_swapped_guards(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_limit_swapped_guards' +; CHECK-NEXT: Determining loop execution counts for: @smin_limit_swapped_guards +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 smin %x1) smax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sge i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %pre.x1 = icmp sge i64 %x1, %bound + call void @llvm.assume(i1 %pre.x1) + %lim = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp sgt i64 %lim, %iv + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umax_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umax %x1)) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_limit_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_limit_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_limit_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %bound, %x0 + call void @llvm.assume(i1 %pre.x0) + %lim = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_start_no_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_start_no_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_start_no_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umin %x1)) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umin %x1)) + ((%x0 umin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %start = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umin_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umin_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @umin_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 umin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 umin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.umin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_start_one_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_start_one_guard' +; CHECK-NEXT: Determining loop execution counts for: @smin_start_one_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smin %x1)) + %bound) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp sle i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nsw i64 %iv, 1 + %cond = icmp slt i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @smin_start_pred_mismatch(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'smin_start_pred_mismatch' +; CHECK-NEXT: Determining loop execution counts for: @smin_start_pred_mismatch +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * (%x0 smin %x1)) + ((%x0 smin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * (%x0 smin %x1)) + ((%x0 smin %x1) umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %pre.x0 = icmp ule i64 %x0, %bound + call void @llvm.assume(i1 %pre.x0) + %start = call i64 @llvm.smin.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %start, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %bound + br i1 %cond, label %loop, label %exit + +exit: + ret void +} + +define void @umax_limit_no_guard(i64 %x0, i64 %x1, i64 %bound) { +; CHECK-LABEL: 'umax_limit_no_guard' +; CHECK-NEXT: Determining loop execution counts for: @umax_limit_no_guard +; CHECK-NEXT: Loop %loop: backedge-taken count is ((-1 * %bound) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 -1 +; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-1 * %bound) + (%x0 umax %x1 umax %bound)) +; CHECK-NEXT: Loop %loop: Trip multiple is 1 +; +entry: + %lim = call i64 @llvm.umax.i64(i64 %x0, i64 %x1) + br label %loop + +loop: + %iv = phi i64 [ %bound, %entry ], [ %iv.next, %loop ] + call void @use(i64 %iv) + %iv.next = add nuw i64 %iv, 1 + %cond = icmp ult i64 %iv, %lim + br i1 %cond, label %loop, label %exit + +exit: + ret void +} diff --git a/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll b/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll new file mode 100644 index 0000000000000..25a60cc14761a --- /dev/null +++ b/llvm/test/Transforms/LoopVectorize/early-exit-minmax-trip-count.ll @@ -0,0 +1,330 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6 +; RUN: opt -S -passes=loop-vectorize -enable-early-exit-vectorization -force-vector-width=4 %s | FileCheck %s + +; The loop should be vectorized. The vectorizer needs to prove +; (A umin B) u<= A to establish memory safety from the dereferenceable +; assumption. +; +; long n = umin(count, length); +; for (long i = 0; i < n; i++) +; if (ptr[i] == 0) return null; +; ... +define ptr @deref_umin_trip_count_and_length(i32 %length, ptr %ptr, i64 %count) #0 { +; CHECK-LABEL: define ptr @deref_umin_trip_count_and_length( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[COUNT:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[COUNT_CHECK:%.*]] = icmp ne i64 [[COUNT]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[COUNT_CHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[TRIP_COUNT:%.*]] = call i64 @llvm.umin.i64(i64 [[COUNT]], i64 [[LENGTH_64]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] +; CHECK-NEXT: [[LENGTH_CHECK:%.*]] = icmp ne i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[LENGTH_CHECK]]) +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TRIP_COUNT]], 4 +; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] +; CHECK: [[VECTOR_PH]]: +; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TRIP_COUNT]], 4 +; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TRIP_COUNT]], [[N_MOD_VF]] +; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK: [[VECTOR_BODY]]: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ] +; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[INDEX]] +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[TMP0]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer +; CHECK-NEXT: [[TMP2:%.*]] = freeze <4 x i1> [[TMP1]] +; CHECK-NEXT: [[TMP3:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP2]]) +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[TMP3]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]] +; CHECK: [[VECTOR_BODY_INTERIM]]: +; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: [[MIDDLE_BLOCK]]: +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TRIP_COUNT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[CMP_N]], label %[[DEOPT:.*]], label %[[SCALAR_PH]] +; CHECK: [[VECTOR_EARLY_EXIT]]: +; CHECK-NEXT: br label %[[FOUND:.*]] +; CHECK: [[SCALAR_PH]]: +; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[FOUND]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[TRIP_COUNT]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[DEOPT]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK: [[FOUND]]: +; CHECK-NEXT: ret ptr null +; CHECK: [[DEOPT]]: +; CHECK-NEXT: unreachable +; +entry: + %count_check = icmp ne i64 %count, 0 + call void @llvm.assume(i1 %count_check) + %length.64 = zext i32 %length to i64 + %trip.count = call i64 @llvm.umin.i64(i64 %count, i64 %length.64) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] + %length_check = icmp ne i32 %length, 0 + call void @llvm.assume(i1 %length_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %found, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %trip.count + br i1 %range_check, label %loop, label %deopt + +found: + ret ptr null + +deopt: + unreachable +} + +; The trip count is %c and the dereferenceable region is umin(%a, %b). +define i1 @deref_umin_all_operands_bounded(ptr %ptr, i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: define i1 @deref_umin_all_operands_bounded( +; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[GUARD_A:%.*]] = icmp ule i64 [[C]], [[A]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_A]]) +; CHECK-NEXT: [[GUARD_B:%.*]] = icmp ule i64 [[C]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_B]]) +; CHECK-NEXT: [[GUARD_POS:%.*]] = icmp ugt i64 [[C]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_POS]]) +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umin.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[C]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %guard.a = icmp ule i64 %c, %a + call void @llvm.assume(i1 %guard.a) + %guard.b = icmp ule i64 %c, %b + call void @llvm.assume(i1 %guard.b) + %guard.pos = icmp ugt i64 %c, 0 + call void @llvm.assume(i1 %guard.pos) + %deref = call i64 @llvm.umin.i64(i64 %a, i64 %b) + call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 %deref) ] + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %c + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; Same as above, but the guards are written in swapped (uge) form. +define i1 @deref_umin_swapped_guards(ptr %ptr, i64 %a, i64 %b, i64 %c) #0 { +; CHECK-LABEL: define i1 @deref_umin_swapped_guards( +; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]], i64 [[C:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[GUARD_A:%.*]] = icmp uge i64 [[A]], [[C]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_A]]) +; CHECK-NEXT: [[GUARD_B:%.*]] = icmp uge i64 [[B]], [[C]] +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_B]]) +; CHECK-NEXT: [[GUARD_POS:%.*]] = icmp ugt i64 [[C]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[GUARD_POS]]) +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umin.i64(i64 [[A]], i64 [[B]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[C]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %guard.a = icmp uge i64 %a, %c + call void @llvm.assume(i1 %guard.a) + %guard.b = icmp uge i64 %b, %c + call void @llvm.assume(i1 %guard.b) + %guard.pos = icmp ugt i64 %c, 0 + call void @llvm.assume(i1 %guard.pos) + %deref = call i64 @llvm.umin.i64(i64 %a, i64 %b) + call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %ptr, i64 %deref) ] + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %c + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; The trip count is a signed smin of the loop count and a sext'd length. Memory +; safety needs smin(%count, %length) s<= %length, which only the signed "any_of" +; min case proves (the removed unsigned umin fast-path could not reason about a +; signed smin at all). +define i1 @smin_signed_trip_count(i32 %length, ptr %ptr, i64 %count) #0 { +; CHECK-LABEL: define i1 @smin_signed_trip_count( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[COUNT:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[POSCHECK:%.*]] = icmp sgt i64 [[COUNT]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[POSCHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = sext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[EXIT:%.*]] = call i64 @llvm.smin.i64(i64 [[COUNT]], i64 [[LENGTH_64]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] +; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp sgt i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[NULL_CHECK]]) +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp slt i64 [[IV_NEXT]], [[EXIT]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %poscheck = icmp sgt i64 %count, 0 + call void @llvm.assume(i1 %poscheck) + %length.64 = sext i32 %length to i64 + %exit = call i64 @llvm.smin.i64(i64 %count, i64 %length.64) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] + %null_check = icmp sgt i32 %length, 0 + call void @llvm.assume(i1 %null_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp slt i64 %iv.next, %exit + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +; The dereferenceable size is umax(%length, %k) and the trip count is %length. +; Memory safety needs %length u<= umax(%length, %k), which only holds because +; %length is itself an operand of the umax ("any_of" max case). +define i1 @umax_deref_bound(i32 %length, ptr %ptr, i64 %k) #0 { +; CHECK-LABEL: define i1 @umax_deref_bound( +; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[K:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[POSCHECK:%.*]] = icmp sgt i64 [[K]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[POSCHECK]]) +; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 +; CHECK-NEXT: [[DEREF:%.*]] = call i64 @llvm.umax.i64(i64 [[LENGTH_64]], i64 [[K]]) +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[DEREF]]) ] +; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp ne i32 [[LENGTH]], 0 +; CHECK-NEXT: call void @llvm.assume(i1 [[NULL_CHECK]]) +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ] +; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] +; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 +; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 +; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[EXIT_0:.*]], label %[[LATCH]] +; CHECK: [[LATCH]]: +; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[LENGTH_64]] +; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[EXIT_1:.*]] +; CHECK: [[EXIT_0]]: +; CHECK-NEXT: ret i1 true +; CHECK: [[EXIT_1]]: +; CHECK-NEXT: ret i1 false +; +entry: + %poscheck = icmp sgt i64 %k, 0 + call void @llvm.assume(i1 %poscheck) + %length.64 = zext i32 %length to i64 + %deref = call i64 @llvm.umax.i64(i64 %length.64, i64 %k) + call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %deref) ] + %null_check = icmp ne i32 %length, 0 + call void @llvm.assume(i1 %null_check) + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ] + %element_gep = getelementptr i8, ptr %ptr, i64 %iv + %element = load i8, ptr %element_gep, align 1 + %found_check = icmp eq i8 %element, 0 + br i1 %found_check, label %exit.0, label %latch + +latch: + %iv.next = add i64 %iv, 1 + %range_check = icmp ult i64 %iv.next, %length.64 + br i1 %range_check, label %loop, label %exit.1 + +exit.0: + ret i1 true + +exit.1: + ret i1 false +} + +attributes #0 = { nofree nosync } diff --git a/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll b/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll deleted file mode 100644 index 202c839e44aad..0000000000000 --- a/llvm/test/Transforms/LoopVectorize/early-exit-umin-trip-count.ll +++ /dev/null @@ -1,103 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6 -; RUN: opt -S -passes=loop-vectorize %s | FileCheck %s - -; The loop should be vectorized. The vectorizer needs to prove -; (A umin B) u<= A to establish memory safety from the dereferenceable -; assumption. -; -; long n = umin(count, length); -; for (long i = 0; i < n; i++) -; if (ptr[i] == 0) return null; -; ... -define ptr @main(i32 %length, ptr %ptr, i64 %0) #0 { -; CHECK-LABEL: define ptr @main( -; CHECK-SAME: i32 [[LENGTH:%.*]], ptr [[PTR:%.*]], i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { -; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[NULL_CHECK0:%.*]] = icmp eq i64 [[TMP0]], 0 -; CHECK-NEXT: br i1 [[NULL_CHECK0]], label %[[DEOPT:.*]], label %[[PREHEADER:.*]] -; CHECK: [[PREHEADER]]: -; CHECK-NEXT: [[LENGTH_64:%.*]] = zext i32 [[LENGTH]] to i64 -; CHECK-NEXT: [[EXIT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP0]], i64 [[LENGTH_64]]) -; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[PTR]], i64 8), "dereferenceable"(ptr [[PTR]], i64 [[LENGTH_64]]) ] -; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i32 [[LENGTH]], 0 -; CHECK-NEXT: br i1 [[NULL_CHECK]], label %[[DEOPT]], label %[[SCALAR_PH1:.*]] -; CHECK: [[SCALAR_PH1]]: -; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[EXIT]], 4 -; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] -; CHECK: [[VECTOR_PH]]: -; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[EXIT]], 4 -; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[EXIT]], [[N_MOD_VF]] -; CHECK-NEXT: br label %[[LOOP1:.*]] -; CHECK: [[LOOP1]]: -; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY_INTERIM:.*]] ] -; CHECK-NEXT: [[ELEMENT_GEP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV1]] -; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i8>, ptr [[ELEMENT_GEP1]], align 1 -; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <4 x i8> [[WIDE_LOAD]], zeroinitializer -; CHECK-NEXT: [[TMP3:%.*]] = freeze <4 x i1> [[TMP2]] -; CHECK-NEXT: [[TMP4:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP3]]) -; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[IV1]], 4 -; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] -; CHECK-NEXT: br i1 [[TMP4]], label %[[VECTOR_EARLY_EXIT:.*]], label %[[VECTOR_BODY_INTERIM]] -; CHECK: [[VECTOR_BODY_INTERIM]]: -; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[LOOP1]], !llvm.loop [[LOOP0:![0-9]+]] -; CHECK: [[MIDDLE_BLOCK]]: -; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[EXIT]], [[N_VEC]] -; CHECK-NEXT: br i1 [[CMP_N]], label %[[DEOPT_LOOPEXIT:.*]], label %[[SCALAR_PH]] -; CHECK: [[VECTOR_EARLY_EXIT]]: -; CHECK-NEXT: br label %[[FOUND:.*]] -; CHECK: [[SCALAR_PH]]: -; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[SCALAR_PH1]] ] -; CHECK-NEXT: br label %[[LOOP:.*]] -; CHECK: [[LOOP]]: -; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], %[[LATCH:.*]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ] -; CHECK-NEXT: [[ELEMENT_GEP:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IV]] -; CHECK-NEXT: [[ELEMENT:%.*]] = load i8, ptr [[ELEMENT_GEP]], align 1 -; CHECK-NEXT: [[FOUND_CHECK:%.*]] = icmp eq i8 [[ELEMENT]], 0 -; CHECK-NEXT: br i1 [[FOUND_CHECK]], label %[[FOUND]], label %[[LATCH]] -; CHECK: [[LATCH]]: -; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 -; CHECK-NEXT: [[RANGE_CHECK:%.*]] = icmp ult i64 [[IV_NEXT]], [[EXIT]] -; CHECK-NEXT: br i1 [[RANGE_CHECK]], label %[[LOOP]], label %[[DEOPT_LOOPEXIT]], !llvm.loop [[LOOP3:![0-9]+]] -; CHECK: [[FOUND]]: -; CHECK-NEXT: ret ptr null -; CHECK: [[DEOPT_LOOPEXIT]]: -; CHECK-NEXT: br label %[[DEOPT]] -; CHECK: [[DEOPT]]: -; CHECK-NEXT: unreachable -; -entry: - %null_check0 = icmp eq i64 %0, 0 - br i1 %null_check0, label %deopt, label %preheader - -preheader: ; preds = %entry - %length.64 = zext i32 %length to i64 - %exit = call i64 @llvm.umin.i64(i64 %0, i64 %length.64) - call void @llvm.assume(i1 true) [ "align"(ptr %ptr, i64 8), "dereferenceable"(ptr %ptr, i64 %length.64) ] - %null_check = icmp eq i32 %length, 0 - br i1 %null_check, label %deopt, label %loop - -loop: ; preds = %latch, %preheader - %iv = phi i64 [ %iv.next, %latch ], [ 0, %preheader ] - %element_gep = getelementptr i8, ptr %ptr, i64 %iv - %element = load i8, ptr %element_gep, align 1 - %found_check = icmp eq i8 %element, 0 - br i1 %found_check, label %found, label %latch - -latch: ; preds = %loop - %iv.next = add i64 %iv, 1 - %range_check = icmp ult i64 %iv.next, %exit - br i1 %range_check, label %loop, label %deopt - -found: ; preds = %loop - ret ptr null - -deopt: ; preds = %latch, %preheader - unreachable -} - -declare i64 @llvm.umin.i64(i64, i64) - -declare void @llvm.assume(i1 noundef) - -attributes #0 = { nofree nosync } - From 3e4f56bdecac68443e37df22965ce47d6b0bd113 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Thu, 9 Jul 2026 20:57:34 +0100 Subject: [PATCH 012/125] [VPlan] Introduce VPlan-based hasTailFolded helper. (NFC) (#208329) After having dedicated support for modeling the header mask of a region created for tail-folding, add a new helper to query if a plan has it's tail folded, i.e. it has a header mask (materialized or not). Similarly to https://github.com/llvm/llvm-project/pull/207784, it also adds a wrapper to LoopVectorizationPlanner that asserts that cost model and VPlan decision agree. The wrapper should be removed after no divergence are found. PR: https://github.com/llvm/llvm-project/pull/208329 --- .../Vectorize/LoopVectorizationPlanner.h | 4 +++ .../Transforms/Vectorize/LoopVectorize.cpp | 30 +++++++++++-------- llvm/lib/Transforms/Vectorize/VPlan.h | 6 ++++ .../Transforms/Vectorize/VPlanTransforms.cpp | 4 +-- .../Transforms/Vectorize/VPlanTransforms.h | 3 +- 5 files changed, 31 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index c5524d01fa76e..1e48aea0fc061 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -970,6 +970,10 @@ class LoopVectorizationPlanner { /// loop. Asserts that the VPlan decision matches the legacy cost model. bool requiresScalarEpilogue(VPlan &Plan, ElementCount VF) const; + /// Returns true if \p Plan folds the tail by masking. Asserts that the + /// VPlan-based decision matches the legacy cost model. + bool hasTailFolded(const VPlan &Plan) const; + /// Attach the runtime checks of \p RTChecks to \p Plan. void attachRuntimeChecks(VPlan &Plan, GeneratedRTChecks &RTChecks, bool HasBranchWeights) const; diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 19b77e40a4103..6e94d36cd8fb1 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3620,7 +3620,7 @@ std::unique_ptr LoopVectorizationPlanner::selectBestEpiloguePlan( } if (Result.Width.isScalar() || - isMoreProfitable(NextVF, Result, MaxTripCount, !CM.foldTailByMasking(), + isMoreProfitable(NextVF, Result, MaxTripCount, !hasTailFolded(MainPlan), /*IsEpilogue*/ true)) { Result = NextVF; BestPlan = &CurrentPlan; @@ -5672,7 +5672,7 @@ LoopVectorizationPlanner::precomputeCosts(VPlan &Plan, ElementCount VF, // TODO: Remove this code after stepping away from the legacy cost model and // adding code to simplify VPlans before calculating their costs. auto TC = getSmallConstantTripCount(PSE.getSE(), OrigLoop); - if (TC == VF && !CM.foldTailByMasking()) + if (TC == VF && !hasTailFolded(Plan)) addFullyUnrolledInstructionsToIgnore(OrigLoop, Legal->getInductionVars(), CostCtx.SkipCostComputation); @@ -5929,7 +5929,7 @@ DenseMap LoopVectorizationPlanner::executePlan( } if (CM.maskPartialAliasing()) { - assert(CM.foldTailByMasking() && "Expected tail folding to be enabled"); + assert(BestVPlan.hasTailFolded() && "Expected tail folding to be enabled"); RUN_VPLAN_PASS(VPlanTransforms::materializeAliasMaskCheckBlock, BestVPlan, *CM.Legal->getRuntimePointerChecking()->getDiffChecks(), HasBranchWeights); @@ -5969,6 +5969,7 @@ DenseMap LoopVectorizationPlanner::executePlan( RUN_VPLAN_PASS(VPlanTransforms::convertEVLExitCond, BestVPlan); // Regions are dissolved after optimizing for VF and UF, which completely // removes unneeded loop regions first. + const bool HasTailFolded = hasTailFolded(BestVPlan); RUN_VPLAN_PASS(VPlanTransforms::dissolveLoopRegions, BestVPlan); // Expand BranchOnTwoConds after dissolution, when latch has direct access to // its successors. @@ -5986,7 +5987,7 @@ DenseMap LoopVectorizationPlanner::executePlan( assert((OrigLoop->getUniqueLatchExitBlock() || RequiresScalarEpilogue) && "loops not exiting via the latch without required epilogue?"); VPlanTransforms::materializeVectorTripCount( - BestVPlan, VectorPH, CM.foldTailByMasking(), RequiresScalarEpilogue, + BestVPlan, VectorPH, HasTailFolded, RequiresScalarEpilogue, &BestVPlan.getVFxUF(), MaxRuntimeStep); VPlanTransforms::materializeFactors(BestVPlan, VectorPH, BestVF); // Limit expansions to VPInstruction to when not vectorizing the epilogue. @@ -6197,9 +6198,9 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(VPInstruction *VPI, : VPI->getOperand(1); if (Consecutive) { Builder.setInsertPoint(VPI); - Ptr = Builder.createConsecutiveVectorPointer( - Ptr, getLoadStoreType(I), Reverse, CM.foldTailByMasking(), - VPI->getDebugLoc()); + Ptr = Builder.createConsecutiveVectorPointer(Ptr, getLoadStoreType(I), + Reverse, Plan.hasTailFolded(), + VPI->getDebugLoc()); } if (Reverse && Mask) @@ -6638,8 +6639,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan, if (!RUN_VPLAN_PASS(VPlanTransforms::tryToConvertVPInstructionsToVPRecipes, *Plan, *TLI)) return nullptr; - RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE, - /*FoldTail=*/false); + RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE); return Plan; } @@ -6808,8 +6808,7 @@ VPlanPtr LoopVectorizationPlanner::tryToBuildVPlan(VPlanPtr Plan, // Optimize FindIV reductions to use sentinel-based approach when possible. RUN_VPLAN_PASS(VPlanTransforms::optimizeFindIVReductions, *Plan, PSE, *OrigLoop); - RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE, - CM.foldTailByMasking()); + RUN_VPLAN_PASS(VPlanTransforms::optimizeInductionLiveOutUsers, *Plan, PSE); // Apply mandatory transformation to handle reductions with multiple in-loop // uses if possible, bail out otherwise. @@ -7126,6 +7125,13 @@ bool LoopVectorizationPlanner::requiresScalarEpilogue(VPlan &Plan, return Result; } +bool LoopVectorizationPlanner::hasTailFolded(const VPlan &Plan) const { + bool Result = Plan.hasTailFolded(); + assert(CM.foldTailByMasking() == Result && + "CM.foldTailByMasking and the VPlan-based check must agree"); + return Result; +} + void LoopVectorizationPlanner::addMinimumIterationCheck( VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount) const { @@ -7135,7 +7141,7 @@ void LoopVectorizationPlanner::addMinimumIterationCheck( : nullptr; RUN_VPLAN_PASS(VPlanTransforms::addMinimumIterationCheck, Plan, VF, UF, MinProfitableTripCount, requiresScalarEpilogue(Plan, VF), - CM.foldTailByMasking(), OrigLoop, BranchWeights, + hasTailFolded(Plan), OrigLoop, BranchWeights, OrigLoop->getLoopPredecessor()->getTerminator()->getDebugLoc(), PSE, Plan.getEntry()); } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 3f9bb6f44497c..eefe02b3e41ad 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -4894,6 +4894,12 @@ class VPlan { /// loop region contains a nested loop region. LLVM_ABI_FOR_TEST bool isOuterLoop() const; + /// Returns true if the vector loop region is tail-folded. + bool hasTailFolded() const { + const VPRegionBlock *LoopRegion = getVectorLoopRegion(); + return LoopRegion && LoopRegion->getHeaderMask(); + } + /// Returns the 'middle' block of the plan, that is the block that selects /// whether to execute the scalar tail loop or the exit block from the loop /// latch. If there is an early exit from the vector loop, the middle block diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 1bae8b6402932..343ee02007966 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -1153,14 +1153,14 @@ optimizeLatchExitInductionUser(VPlan &Plan, VPValue *Op, } void VPlanTransforms::optimizeInductionLiveOutUsers( - VPlan &Plan, PredicatedScalarEvolution &PSE, bool FoldTail) { + VPlan &Plan, PredicatedScalarEvolution &PSE) { // Compute end values for all inductions. VPRegionBlock *VectorRegion = Plan.getVectorLoopRegion(); auto *VectorPH = cast(VectorRegion->getSinglePredecessor()); VPBuilder VectorPHBuilder(VectorPH, VectorPH->begin()); DenseMap EndValues; VPValue *ResumeTC = - FoldTail ? Plan.getTripCount() : &Plan.getVectorTripCount(); + Plan.hasTailFolded() ? Plan.getTripCount() : &Plan.getVectorTripCount(); for (auto &Phi : VectorRegion->getEntryBasicBlock()->phis()) { auto *WideIV = dyn_cast(&Phi); if (!WideIV) diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h index 2158d6a0cc67d..85375625d34b5 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h @@ -416,8 +416,7 @@ struct VPlanTransforms { /// IV values by feeding them precomputed end values instead, possibly taken /// one step backwards. static void optimizeInductionLiveOutUsers(VPlan &Plan, - PredicatedScalarEvolution &PSE, - bool FoldTail); + PredicatedScalarEvolution &PSE); /// Add explicit broadcasts for live-ins and VPValues defined in \p Plan's entry block if they are used as vectors. static void materializeBroadcasts(VPlan &Plan); From 5a1b669c0ec2d7dd81751932469ac442e3dfc8d5 Mon Sep 17 00:00:00 2001 From: Krisitan Erik Olsen Date: Thu, 9 Jul 2026 12:58:54 -0700 Subject: [PATCH 013/125] [clang] Fix crash in DiagnoseMissingSemiAfterTagDefinition for annot_template_id (#208119) DiagnoseMissingSemiAfterTagDefinition checks whether the token after a tag definition could be a scope specifier before calling TryAnnotateCXXScopeToken. It accepted annot_template_id unconditionally, but TryAnnotateCXXScopeToken asserts that MightBeCXXScopeToken() holds, which only accepts annot_template_id when followed by ::. When the token is annot_template_id not followed by :: (e.g. union { } ::foo; where ::foo is annotated as a template-id after a missing semicolon), the check passes but MightBeCXXScopeToken() returns false, firing the assertion. This patch adds the same NextToken().is(tok::coloncolon) guard that MightBeCXXScopeToken uses for annot_template_id. Fixes #207992 --------- Co-authored-by: Corentin Jabot --- clang/docs/ReleaseNotes.md | 1 + clang/lib/Parse/ParseDecl.cpp | 4 ++-- clang/test/Parser/cxx-missing-semi-crash.cpp | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 clang/test/Parser/cxx-missing-semi-crash.cpp diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 696aed167e621..dd63b4e5555d4 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -942,6 +942,7 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the immediate-escalated callable. (#GH192846) - Fixed a crash when passing one sized implicitly casted vector to a `abs` function. (#GH204777) - Fixed a crash when diagnosing an invalid out-of-line definition of a member class template. (#GH201490) +- Fixed a crash in the parser when a missing semicolon after a tag definition is followed by a template-id not preceded by `::`. (#GH207992) ### OpenACC Specific Changes diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 3f41e7c5c6f0d..7326ba781184c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3282,8 +3282,8 @@ Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS, DSContext == DeclSpecContext::DSC_top_level); if (getLangOpts().CPlusPlus && - Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype, - tok::annot_template_id) && + (Tok.isOneOf(tok::identifier, tok::coloncolon, tok::kw_decltype) || + (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon))) && TryAnnotateCXXScopeToken(EnteringContext)) { SkipMalformedDecl(); return true; diff --git a/clang/test/Parser/cxx-missing-semi-crash.cpp b/clang/test/Parser/cxx-missing-semi-crash.cpp new file mode 100644 index 0000000000000..bed8a2633a618 --- /dev/null +++ b/clang/test/Parser/cxx-missing-semi-crash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s + +// Ensure no crash when DiagnoseMissingSemiAfterTagDefinition encounters an +// annot_template_id not followed by '::'. + +namespace GH207992 { +template void foo(); // expected-note {{'foo' declared here}} +void bar() { + union { + } ::foo; // expected-error {{no template named 'foo' in the global namespace; did you mean simply 'foo'?}} \ + // expected-error {{template specialization requires 'template<>'}} +} +} // namespace N +// expected-error@* {{templates can only be declared in namespace or class scope}} From fedcedef0665f3be419baa7c198123fd65b72538 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Thu, 9 Jul 2026 13:00:07 -0700 Subject: [PATCH 014/125] [RISCV] Fix incorrect fixed vector lowering for VECTOR_DEINTERLEAVE (#207254) Partially address #207136 Previously this part of the logic simply converts each operand into scalable vector and pass on. This will run into problem when the scalable vector container is larger than the actual fixed vector. This patch fixes this issue by storing individual fixed vector operands directly onto the stack, before loading them back with segmented load just like its scalable vector counterpart --- llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 110 +- .../RISCV/rvv/vector-deinterleave-fixed.ll | 1070 ++++++++++------- 2 files changed, 722 insertions(+), 458 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c0b69d50f8fef..2c8f05d2d298a 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -13213,27 +13213,14 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, if (VecVT.getVectorElementType() == MVT::i1) return widenVectorOpsToi8(Op, DL, DAG); - // Convert to scalable vectors first. - if (VecVT.isFixedLengthVector()) { - MVT ContainerVT = getContainerForFixedLengthVector(VecVT); - SmallVector Ops(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Ops[i] = convertToScalableVector(ContainerVT, Op.getOperand(i), DAG, - Subtarget); - - SmallVector VTs(Factor, ContainerVT); - SDValue NewDeinterleave = - DAG.getNode(ISD::VECTOR_DEINTERLEAVE, DL, VTs, Ops); + bool IsFixedVector = VecVT.isFixedLengthVector(); - SmallVector Res(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Res[i] = convertFromScalableVector(VecVT, NewDeinterleave.getValue(i), - DAG, Subtarget); - return DAG.getMergeValues(Res, DL); - } + MVT ContainerVecVT = VecVT; + if (IsFixedVector) + ContainerVecVT = getContainerForFixedLengthVector(VecVT); // If concatenating would exceed LMUL=8, we need to split. - if ((VecVT.getSizeInBits().getKnownMinValue() * Factor) > + if ((ContainerVecVT.getSizeInBits().getKnownMinValue() * Factor) > (8 * RISCV::RVVBitsPerBlock)) { SmallVector Ops(Factor * 2); for (unsigned i = 0; i != Factor; ++i) { @@ -13257,7 +13244,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, return DAG.getMergeValues(Res, DL); } - if (Subtarget.hasStdExtZvzip() && Factor == 2) { + if (Subtarget.hasStdExtZvzip() && Factor == 2 && !IsFixedVector) { MVT VT = Op->getSimpleValueType(0); MVT NewVT = VT.getDoubleNumVectorElementsVT(); if (isTypeLegal(NewVT) && isLegalVTForZvzipOperand(VT, Subtarget)) { @@ -13283,7 +13270,7 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, Ops.append(PowerOf2Ceil(Factor) - Factor, DAG.getUNDEF(VecVT)); SDValue Concat = DAG.getNode(ISD::CONCAT_VECTORS, DL, ConcatVT, Ops); - if (Factor == 2) { + if (Factor == 2 && !IsFixedVector) { // We can deinterleave through vnsrl.wi if the element type is smaller than // ELEN if (VecVT.getScalarSizeInBits() < Subtarget.getELen()) { @@ -13322,27 +13309,63 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, } // Store with unit-stride store and load it back with segmented load. + SDValue Mask, VL; MVT XLenVT = Subtarget.getXLenVT(); - auto [Mask, VL] = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget); - SDValue Passthru = DAG.getUNDEF(ConcatVT); - - // Allocate a stack slot. - Align Alignment = DAG.getReducedAlign(VecVT, /*UseABI=*/false); - SDValue StackPtr = - DAG.CreateStackTemporary(ConcatVT.getStoreSize(), Alignment); auto &MF = DAG.getMachineFunction(); - auto FrameIndex = cast(StackPtr.getNode())->getIndex(); - auto PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + SDValue Chain = DAG.getEntryNode(); + Align Alignment = DAG.getReducedAlign(VecVT, /*UseABI=*/false); + SDValue StackPtr; + MachinePointerInfo PtrInfo; + if (IsFixedVector) { + // Calculating the stack size. + ElementCount ActualConcatEC = + VecVT.getVectorElementCount().multiplyCoefficientBy(Factor); + EVT ConcatEVT = EVT::getVectorVT( + *DAG.getContext(), VecVT.getVectorElementType(), ActualConcatEC); + StackPtr = DAG.CreateStackTemporary(ConcatEVT.getStoreSize(), Alignment); + auto FrameIndex = cast(StackPtr.getNode())->getIndex(); + PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + + // If this is a fixed vector, instead of using the concat vector, we simply + // store each fixed vector operand directly onto the stack, individually. + // The reason being that if the fixed vector is (much) smaller than the + // container vector, we will be wasting space on stack. + TypeSize VecSize = VecVT.getStoreSize(); + SDValue BasePtr = StackPtr; + MachinePointerInfo PI = PtrInfo; + SmallVector Tokens(Factor); + for (auto [Idx, FieldOp] : enumerate(Op->op_values())) { + if (Idx) { + // Advance the pointer. + BasePtr = DAG.getObjectPtrOffset(DL, BasePtr, VecSize); + PI = PI.getWithOffset(VecSize); + } + Tokens[Idx] = DAG.getStore(Chain, DL, FieldOp, BasePtr, PI, Alignment); + } + Chain = DAG.getTokenFactor(DL, Tokens); - SDValue StoreOps[] = {DAG.getEntryNode(), - DAG.getTargetConstant(Intrinsic::riscv_vse, DL, XLenVT), - Concat, StackPtr, VL}; + // Calculating Mask and VL for later usages. + std::tie(Mask, VL) = + getDefaultVLOps(VecVT, ContainerVecVT, DL, DAG, Subtarget); + ConcatVT = getContainerForFixedLengthVector(ConcatVT); + } else { + std::tie(Mask, VL) = getDefaultScalableVLOps(VecVT, DL, DAG, Subtarget); + StackPtr = DAG.CreateStackTemporary(ConcatVT.getStoreSize(), Alignment); + auto FrameIndex = cast(StackPtr.getNode())->getIndex(); + PtrInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex); + + SDValue StoreOps[] = { + Chain, DAG.getTargetConstant(Intrinsic::riscv_vse, DL, XLenVT), Concat, + StackPtr, VL}; - SDValue Chain = DAG.getMemIntrinsicNode( - ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), StoreOps, - ConcatVT.getVectorElementType(), PtrInfo, Alignment, - MachineMemOperand::MOStore, LocationSize::beforeOrAfterPointer()); + Chain = DAG.getMemIntrinsicNode( + ISD::INTRINSIC_VOID, DL, DAG.getVTList(MVT::Other), StoreOps, + ConcatVT.getVectorElementType(), PtrInfo, Alignment, + MachineMemOperand::MOStore, LocationSize::beforeOrAfterPointer()); + } + // Load it back with segmented load. + SDValue Passthru = DAG.getUNDEF(ConcatVT); static const Intrinsic::ID VlsegIntrinsicsIds[] = { Intrinsic::riscv_vlseg2_mask, Intrinsic::riscv_vlseg3_mask, Intrinsic::riscv_vlseg4_mask, Intrinsic::riscv_vlseg5_mask, @@ -13360,8 +13383,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, RISCVVType::TAIL_AGNOSTIC | RISCVVType::MASK_AGNOSTIC, DL, XLenVT), DAG.getTargetConstant(Log2_64(VecVT.getScalarSizeInBits()), DL, XLenVT)}; - unsigned Sz = - Factor * VecVT.getVectorMinNumElements() * VecVT.getScalarSizeInBits(); + unsigned Sz = Factor * ContainerVecVT.getVectorMinNumElements() * + ContainerVecVT.getScalarSizeInBits(); EVT VecTupTy = MVT::getRISCVVectorTupleVT(Sz, Factor); SDValue Load = DAG.getMemIntrinsicNode( @@ -13371,9 +13394,14 @@ SDValue RISCVTargetLowering::lowerVECTOR_DEINTERLEAVE(SDValue Op, SmallVector Res(Factor); - for (unsigned i = 0U; i < Factor; ++i) - Res[i] = DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, VecVT, Load, - DAG.getTargetConstant(i, DL, MVT::i32)); + for (unsigned i = 0U; i < Factor; ++i) { + SDValue FieldRes = + DAG.getNode(RISCVISD::TUPLE_EXTRACT, DL, ContainerVecVT, Load, + DAG.getTargetConstant(i, DL, MVT::i32)); + if (IsFixedVector) + FieldRes = convertFromScalableVector(VecVT, FieldRes, DAG, Subtarget); + Res[i] = FieldRes; + } return DAG.getMergeValues(Res, DL); } diff --git a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll index 07fb8675d85e8..bce071e988f0e 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vector-deinterleave-fixed.ll @@ -182,27 +182,20 @@ define {<8 x i64>, <8 x i64>} @vector_deinterleave_v8i64_v16i64(<16 x i64> %vec) define {<2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave3_v2i32_v6i32(<6 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave3_v2i32_v6i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 2 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i32>, <2 x i32>, <2 x i32>} @llvm.vector.deinterleave3.v6i32(<6 x i32> %v) ret {<2 x i32>, <2 x i32>, <2 x i32>} %res @@ -211,55 +204,341 @@ define {<2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave3_v2i32_v6i32(<6 x define {<3 x i32>, <3 x i32>, <3 x i32>} @vector_deinterleave3_v3i32_v9i32(<9 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave3_v3i32_v9i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 2 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -48 ; CHECK-NEXT: vsetivli zero, 4, e32, m4, ta, ma ; CHECK-NEXT: vslidedown.vi v12, v8, 8 ; CHECK-NEXT: vsetivli zero, 4, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: vmv2r.v v10, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs4r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 32 +; CHECK-NEXT: vse32.v v12, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 2 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 48 ; CHECK-NEXT: ret %d = call {<3 x i32>, <3 x i32>, <3 x i32>} @llvm.vector.deinterleave3(<9 x i32> %v) ret {<3 x i32>, <3 x i32>, <3 x i32>} %d } +define {<15 x i32>, <15 x i32>, <15 x i32>} @vector_deinterleave3_v15i32_v45i32(<45 x i32> %v) nounwind { +; RV32-LABEL: vector_deinterleave3_v15i32_v45i32: +; RV32: # %bb.0: +; RV32-NEXT: addi sp, sp, -640 +; RV32-NEXT: sw ra, 636(sp) # 4-byte Folded Spill +; RV32-NEXT: sw s0, 632(sp) # 4-byte Folded Spill +; RV32-NEXT: addi s0, sp, 640 +; RV32-NEXT: andi sp, sp, -128 +; RV32-NEXT: addi a1, sp, 252 +; RV32-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV32-NEXT: vse32.v v23, (a1) +; RV32-NEXT: addi a1, sp, 248 +; RV32-NEXT: vse32.v v22, (a1) +; RV32-NEXT: addi a1, sp, 244 +; RV32-NEXT: vse32.v v21, (a1) +; RV32-NEXT: addi a1, sp, 240 +; RV32-NEXT: vse32.v v20, (a1) +; RV32-NEXT: addi a1, sp, 236 +; RV32-NEXT: vse32.v v19, (a1) +; RV32-NEXT: addi a1, sp, 232 +; RV32-NEXT: vse32.v v18, (a1) +; RV32-NEXT: addi a1, sp, 228 +; RV32-NEXT: vse32.v v17, (a1) +; RV32-NEXT: addi a1, sp, 224 +; RV32-NEXT: vse32.v v16, (a1) +; RV32-NEXT: addi a1, sp, 220 +; RV32-NEXT: vse32.v v15, (a1) +; RV32-NEXT: addi a1, sp, 216 +; RV32-NEXT: vse32.v v14, (a1) +; RV32-NEXT: addi a1, sp, 212 +; RV32-NEXT: vse32.v v13, (a1) +; RV32-NEXT: addi a1, sp, 208 +; RV32-NEXT: vse32.v v12, (a1) +; RV32-NEXT: addi a1, sp, 204 +; RV32-NEXT: vse32.v v11, (a1) +; RV32-NEXT: addi a1, sp, 200 +; RV32-NEXT: vse32.v v10, (a1) +; RV32-NEXT: addi a1, sp, 196 +; RV32-NEXT: vse32.v v9, (a1) +; RV32-NEXT: addi a1, sp, 192 +; RV32-NEXT: vse32.v v8, (a1) +; RV32-NEXT: addi a2, a0, 64 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vle32.v v8, (a2) +; RV32-NEXT: addi a2, sp, 384 +; RV32-NEXT: vse32.v v8, (a2) +; RV32-NEXT: addi a3, a0, 96 +; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; RV32-NEXT: vle32.v v8, (a3) +; RV32-NEXT: addi a3, sp, 416 +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v8, (a0) +; RV32-NEXT: addi a3, sp, 64 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v12, (a1) +; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV32-NEXT: vslidedown.vi v16, v12, 8 +; RV32-NEXT: mv a1, sp +; RV32-NEXT: vslidedown.vi v8, v8, 8 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v12, (a1) +; RV32-NEXT: addi a3, sp, 32 +; RV32-NEXT: vse32.v v16, (a3) +; RV32-NEXT: addi a3, sp, 96 +; RV32-NEXT: vse32.v v8, (a3) +; RV32-NEXT: lw a0, 112(a0) +; RV32-NEXT: sw a0, 432(sp) +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vle32.v v8, (a2) +; RV32-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV32-NEXT: vslidedown.vi v12, v8, 8 +; RV32-NEXT: addi a0, sp, 128 +; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV32-NEXT: vse32.v v8, (a0) +; RV32-NEXT: addi a0, sp, 160 +; RV32-NEXT: vse32.v v12, (a0) +; RV32-NEXT: vlseg3e32.v v20, (a3) +; RV32-NEXT: vlseg3e32.v v12, (a1) +; RV32-NEXT: vmv4r.v v28, v20 +; RV32-NEXT: vmv2r.v v30, v8 +; RV32-NEXT: vmv4r.v v8, v12 +; RV32-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV32-NEXT: vslideup.vi v8, v28, 8 +; RV32-NEXT: vmv2r.v v12, v14 +; RV32-NEXT: vmv2r.v v20, v22 +; RV32-NEXT: vslideup.vi v12, v20, 8 +; RV32-NEXT: vslideup.vi v16, v24, 8 +; RV32-NEXT: addi sp, s0, -640 +; RV32-NEXT: lw ra, 636(sp) # 4-byte Folded Reload +; RV32-NEXT: lw s0, 632(sp) # 4-byte Folded Reload +; RV32-NEXT: addi sp, sp, 640 +; RV32-NEXT: ret +; +; RV64-LABEL: vector_deinterleave3_v15i32_v45i32: +; RV64: # %bb.0: +; RV64-NEXT: addi sp, sp, -640 +; RV64-NEXT: sd ra, 632(sp) # 8-byte Folded Spill +; RV64-NEXT: sd s0, 624(sp) # 8-byte Folded Spill +; RV64-NEXT: addi s0, sp, 640 +; RV64-NEXT: andi sp, sp, -128 +; RV64-NEXT: addi a1, a0, 112 +; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV64-NEXT: vle32.v v24, (a1) +; RV64-NEXT: addi a1, sp, 252 +; RV64-NEXT: vse32.v v23, (a1) +; RV64-NEXT: addi a1, sp, 248 +; RV64-NEXT: vse32.v v22, (a1) +; RV64-NEXT: addi a1, sp, 244 +; RV64-NEXT: vse32.v v21, (a1) +; RV64-NEXT: addi a1, sp, 240 +; RV64-NEXT: vse32.v v20, (a1) +; RV64-NEXT: addi a1, sp, 236 +; RV64-NEXT: vse32.v v19, (a1) +; RV64-NEXT: addi a1, sp, 232 +; RV64-NEXT: vse32.v v18, (a1) +; RV64-NEXT: addi a1, sp, 228 +; RV64-NEXT: vse32.v v17, (a1) +; RV64-NEXT: addi a1, sp, 224 +; RV64-NEXT: vse32.v v16, (a1) +; RV64-NEXT: addi a1, sp, 220 +; RV64-NEXT: vse32.v v15, (a1) +; RV64-NEXT: addi a1, sp, 216 +; RV64-NEXT: vse32.v v14, (a1) +; RV64-NEXT: addi a1, sp, 212 +; RV64-NEXT: vse32.v v13, (a1) +; RV64-NEXT: addi a1, sp, 208 +; RV64-NEXT: vse32.v v12, (a1) +; RV64-NEXT: addi a1, sp, 204 +; RV64-NEXT: vse32.v v11, (a1) +; RV64-NEXT: addi a1, sp, 200 +; RV64-NEXT: vse32.v v10, (a1) +; RV64-NEXT: addi a1, sp, 196 +; RV64-NEXT: vse32.v v9, (a1) +; RV64-NEXT: addi a1, sp, 192 +; RV64-NEXT: vse32.v v8, (a1) +; RV64-NEXT: addi a2, a0, 64 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vle32.v v8, (a2) +; RV64-NEXT: addi a2, sp, 384 +; RV64-NEXT: vse32.v v8, (a2) +; RV64-NEXT: addi a3, a0, 96 +; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; RV64-NEXT: vle32.v v8, (a3) +; RV64-NEXT: addi a3, sp, 416 +; RV64-NEXT: vse32.v v8, (a3) +; RV64-NEXT: addi a3, sp, 432 +; RV64-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; RV64-NEXT: vse32.v v24, (a3) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v8, (a0) +; RV64-NEXT: addi a0, sp, 64 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v8, (a0) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v12, (a1) +; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV64-NEXT: vslidedown.vi v16, v12, 8 +; RV64-NEXT: mv a0, sp +; RV64-NEXT: vslidedown.vi v8, v8, 8 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v12, (a0) +; RV64-NEXT: addi a1, sp, 32 +; RV64-NEXT: vse32.v v16, (a1) +; RV64-NEXT: addi a1, sp, 96 +; RV64-NEXT: vse32.v v8, (a1) +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vle32.v v8, (a2) +; RV64-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; RV64-NEXT: vslidedown.vi v12, v8, 8 +; RV64-NEXT: addi a2, sp, 128 +; RV64-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; RV64-NEXT: vse32.v v8, (a2) +; RV64-NEXT: addi a2, sp, 160 +; RV64-NEXT: vse32.v v12, (a2) +; RV64-NEXT: vlseg3e32.v v20, (a1) +; RV64-NEXT: vlseg3e32.v v12, (a0) +; RV64-NEXT: vmv4r.v v28, v20 +; RV64-NEXT: vmv2r.v v30, v8 +; RV64-NEXT: vmv4r.v v8, v12 +; RV64-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; RV64-NEXT: vslideup.vi v8, v28, 8 +; RV64-NEXT: vmv2r.v v12, v14 +; RV64-NEXT: vmv2r.v v20, v22 +; RV64-NEXT: vslideup.vi v12, v20, 8 +; RV64-NEXT: vslideup.vi v16, v24, 8 +; RV64-NEXT: addi sp, s0, -640 +; RV64-NEXT: ld ra, 632(sp) # 8-byte Folded Reload +; RV64-NEXT: ld s0, 624(sp) # 8-byte Folded Reload +; RV64-NEXT: addi sp, sp, 640 +; RV64-NEXT: ret +; +; ZVZIP-LABEL: vector_deinterleave3_v15i32_v45i32: +; ZVZIP: # %bb.0: +; ZVZIP-NEXT: addi sp, sp, -640 +; ZVZIP-NEXT: sd ra, 632(sp) # 8-byte Folded Spill +; ZVZIP-NEXT: sd s0, 624(sp) # 8-byte Folded Spill +; ZVZIP-NEXT: addi s0, sp, 640 +; ZVZIP-NEXT: andi sp, sp, -128 +; ZVZIP-NEXT: addi a1, a0, 112 +; ZVZIP-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; ZVZIP-NEXT: vle32.v v24, (a1) +; ZVZIP-NEXT: addi a1, sp, 252 +; ZVZIP-NEXT: vse32.v v23, (a1) +; ZVZIP-NEXT: addi a1, sp, 248 +; ZVZIP-NEXT: vse32.v v22, (a1) +; ZVZIP-NEXT: addi a1, sp, 244 +; ZVZIP-NEXT: vse32.v v21, (a1) +; ZVZIP-NEXT: addi a1, sp, 240 +; ZVZIP-NEXT: vse32.v v20, (a1) +; ZVZIP-NEXT: addi a1, sp, 236 +; ZVZIP-NEXT: vse32.v v19, (a1) +; ZVZIP-NEXT: addi a1, sp, 232 +; ZVZIP-NEXT: vse32.v v18, (a1) +; ZVZIP-NEXT: addi a1, sp, 228 +; ZVZIP-NEXT: vse32.v v17, (a1) +; ZVZIP-NEXT: addi a1, sp, 224 +; ZVZIP-NEXT: vse32.v v16, (a1) +; ZVZIP-NEXT: addi a1, sp, 220 +; ZVZIP-NEXT: vse32.v v15, (a1) +; ZVZIP-NEXT: addi a1, sp, 216 +; ZVZIP-NEXT: vse32.v v14, (a1) +; ZVZIP-NEXT: addi a1, sp, 212 +; ZVZIP-NEXT: vse32.v v13, (a1) +; ZVZIP-NEXT: addi a1, sp, 208 +; ZVZIP-NEXT: vse32.v v12, (a1) +; ZVZIP-NEXT: addi a1, sp, 204 +; ZVZIP-NEXT: vse32.v v11, (a1) +; ZVZIP-NEXT: addi a1, sp, 200 +; ZVZIP-NEXT: vse32.v v10, (a1) +; ZVZIP-NEXT: addi a1, sp, 196 +; ZVZIP-NEXT: vse32.v v9, (a1) +; ZVZIP-NEXT: addi a1, sp, 192 +; ZVZIP-NEXT: vse32.v v8, (a1) +; ZVZIP-NEXT: addi a2, a0, 64 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a2) +; ZVZIP-NEXT: addi a2, sp, 384 +; ZVZIP-NEXT: vse32.v v8, (a2) +; ZVZIP-NEXT: addi a3, a0, 96 +; ZVZIP-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a3) +; ZVZIP-NEXT: addi a3, sp, 416 +; ZVZIP-NEXT: vse32.v v8, (a3) +; ZVZIP-NEXT: addi a3, sp, 432 +; ZVZIP-NEXT: vsetivli zero, 1, e32, mf2, ta, ma +; ZVZIP-NEXT: vse32.v v24, (a3) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a0) +; ZVZIP-NEXT: addi a0, sp, 64 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v8, (a0) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v12, (a1) +; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; ZVZIP-NEXT: vslidedown.vi v16, v12, 8 +; ZVZIP-NEXT: mv a0, sp +; ZVZIP-NEXT: vslidedown.vi v8, v8, 8 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v12, (a0) +; ZVZIP-NEXT: addi a1, sp, 32 +; ZVZIP-NEXT: vse32.v v16, (a1) +; ZVZIP-NEXT: addi a1, sp, 96 +; ZVZIP-NEXT: vse32.v v8, (a1) +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vle32.v v8, (a2) +; ZVZIP-NEXT: vsetivli zero, 8, e32, m4, ta, ma +; ZVZIP-NEXT: vslidedown.vi v12, v8, 8 +; ZVZIP-NEXT: addi a2, sp, 128 +; ZVZIP-NEXT: vsetivli zero, 8, e32, m2, ta, ma +; ZVZIP-NEXT: vse32.v v8, (a2) +; ZVZIP-NEXT: addi a2, sp, 160 +; ZVZIP-NEXT: vse32.v v12, (a2) +; ZVZIP-NEXT: vlseg3e32.v v20, (a1) +; ZVZIP-NEXT: vlseg3e32.v v12, (a0) +; ZVZIP-NEXT: vmv4r.v v28, v20 +; ZVZIP-NEXT: vmv2r.v v30, v8 +; ZVZIP-NEXT: vmv4r.v v8, v12 +; ZVZIP-NEXT: vsetivli zero, 16, e32, m4, ta, ma +; ZVZIP-NEXT: vslideup.vi v8, v28, 8 +; ZVZIP-NEXT: vmv2r.v v12, v14 +; ZVZIP-NEXT: vmv2r.v v20, v22 +; ZVZIP-NEXT: vslideup.vi v12, v20, 8 +; ZVZIP-NEXT: vslideup.vi v16, v24, 8 +; ZVZIP-NEXT: addi sp, s0, -640 +; ZVZIP-NEXT: ld ra, 632(sp) # 8-byte Folded Reload +; ZVZIP-NEXT: ld s0, 624(sp) # 8-byte Folded Reload +; ZVZIP-NEXT: addi sp, sp, 640 +; ZVZIP-NEXT: ret + %d = call {<15 x i32>, <15 x i32>, <15 x i32>} @llvm.vector.deinterleave3(<45 x i32> %v) + ret {<15 x i32>, <15 x i32>, <15 x i32>} %d +} + define {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave4_v2i32_v8i32(<8 x i32> %v) nounwind { ; CHECK-LABEL: vector_deinterleave4_v2i32_v8i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 +; CHECK-NEXT: addi sp, sp, -32 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 6 ; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v12, v10, a0 -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv.v.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse32.v v8, (a1) ; CHECK-NEXT: vlseg4e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @llvm.vector.deinterleave4.v8i32(<8 x i32> %v) ret {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} %res @@ -268,33 +547,30 @@ define {<2 x i32>, <2 x i32>, <2 x i32>, <2 x i32>} @vector_deinterleave4_v2i32_ define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterleave5_v2i16_v10i16(<10 x i16> %v) nounwind { ; CHECK-LABEL: vector_deinterleave5_v2i16_v10i16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @llvm.vector.deinterleave5.v10i16(<10 x i16> %v) ret {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} %res @@ -303,35 +579,34 @@ define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterle define {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @vector_deinterleave6_v2i16_v12i16(<12 x i16> %v) nounwind { ; CHECK-LABEL: vector_deinterleave6_v2i16_v12i16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret %res = call {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} @llvm.vector.deinterleave6.v12i16(<12 x i16> %v) ret {<2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>, <2 x i16>} %res @@ -341,37 +616,35 @@ define {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @v ; CHECK-LABEL: vector_deinterleave7_v14i8_v2i8: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 10 -; CHECK-NEXT: vslidedown.vi v10, v8, 8 -; CHECK-NEXT: vslidedown.vi v11, v8, 12 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vslidedown.vi v13, v8, 4 -; CHECK-NEXT: vmv1r.v v14, v8 -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: srli a1, a0, 2 -; CHECK-NEXT: srli a2, a0, 3 -; CHECK-NEXT: vsetvli zero, a1, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v14, v12, a2 -; CHECK-NEXT: add a3, a1, a2 -; CHECK-NEXT: vslideup.vx v10, v9, a2 -; CHECK-NEXT: vsetvli zero, a3, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v14, v13, a1 -; CHECK-NEXT: vslideup.vx v10, v11, a1 -; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v14, v8, a3 -; CHECK-NEXT: srli a0, a0, 1 -; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma -; CHECK-NEXT: vslideup.vx v14, v10, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs1r.v v14, (a0) -; CHECK-NEXT: vsetvli a1, zero, e8, mf8, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 12 +; CHECK-NEXT: vslidedown.vi v10, v8, 10 +; CHECK-NEXT: vslidedown.vi v11, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse8.v v8, (a1) ; CHECK-NEXT: vlseg7e8.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: add sp, sp, a0 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %res = call {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @llvm.vector.deinterleave7.v14i8(<14 x i8> %v) @@ -382,38 +655,40 @@ define {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 ; CHECK-LABEL: vector_deinterleave8_v16i8_v2i8: ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: csrr a0, vlenb ; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 10 -; CHECK-NEXT: vslidedown.vi v10, v8, 8 -; CHECK-NEXT: vslidedown.vi v11, v8, 12 -; CHECK-NEXT: vslidedown.vi v12, v8, 14 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vslidedown.vi v14, v8, 4 -; CHECK-NEXT: vslidedown.vi v15, v8, 6 -; CHECK-NEXT: srli a1, a0, 2 -; CHECK-NEXT: srli a2, a0, 3 -; CHECK-NEXT: vsetvli zero, a1, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v10, v9, a2 -; CHECK-NEXT: vslideup.vx v8, v13, a2 -; CHECK-NEXT: add a2, a1, a2 -; CHECK-NEXT: vsetvli zero, a2, e8, mf2, tu, ma -; CHECK-NEXT: vslideup.vx v10, v11, a1 -; CHECK-NEXT: vslideup.vx v8, v14, a1 -; CHECK-NEXT: vsetvli a1, zero, e8, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v10, v12, a2 -; CHECK-NEXT: vslideup.vx v8, v15, a2 -; CHECK-NEXT: srli a0, a0, 1 -; CHECK-NEXT: vsetvli a1, zero, e8, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v10, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs1r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e8, mf8, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 14 +; CHECK-NEXT: vslidedown.vi v10, v8, 12 +; CHECK-NEXT: vslidedown.vi v11, v8, 10 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse8.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e8, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, ma +; CHECK-NEXT: vse8.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse8.v v8, (a1) ; CHECK-NEXT: vlseg8e8.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: add sp, sp, a0 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %res = call {<2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>, <2 x i8>} @llvm.vector.deinterleave8.v16i8(<16 x i8> %v) @@ -595,30 +870,21 @@ ret {<4 x double>, <4 x double>} %retval define {<2 x float>, <2 x float>, <2 x float>} @vector_deinterleave3_v6f32_v2f32(<6 x float> %v) { ; CHECK-LABEL: vector_deinterleave3_v6f32_v2f32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 2 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 4 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vlseg3e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x float>, <2 x float>, <2 x float>} @llvm.vector.deinterleave3.v6f32(<6 x float> %v) @@ -628,32 +894,25 @@ define {<2 x float>, <2 x float>, <2 x float>} @vector_deinterleave3_v6f32_v2f32 define {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @vector_deinterleave4_v8f32_v2f32(<8 x float> %v) { ; CHECK-LABEL: vector_deinterleave4_v8f32_v2f32: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 6 ; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse32.v v10, (a1) ; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 2 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a0, a0, 3 -; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma -; CHECK-NEXT: vslideup.vx v12, v10, a0 -; CHECK-NEXT: vslideup.vx v8, v9, a0 -; CHECK-NEXT: vmv.v.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma +; CHECK-NEXT: vse32.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse32.v v8, (a1) ; CHECK-NEXT: vlseg4e32.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @llvm.vector.deinterleave4.v8f32(<8 x float> %v) @@ -663,36 +922,31 @@ define {<2 x float>, <2 x float>, <2 x float>, <2 x float>} @vector_deinterleave define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_deinterleave5_v10f16_v2f16(<10 x half> %v) { ; CHECK-LABEL: vector_deinterleave5_v10f16_v2f16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @llvm.vector.deinterleave5.v10f16(<10 x half> %v) @@ -702,36 +956,31 @@ define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_dein define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @vector_deinterleave5_v10bf16_v2bf16(<10 x bfloat> %v) { ; CHECK-LABEL: vector_deinterleave5_v10bf16_v2bf16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: addi a0, sp, 12 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v12, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v10 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg5e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @llvm.vector.deinterleave5.v10bf16(<10 x bfloat> %v) @@ -741,38 +990,35 @@ define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @v define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @vector_deinterleave6_v12f16_v2f16(<12 x half> %v) { ; CHECK-LABEL: vector_deinterleave6_v12f16_v2f16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} @llvm.vector.deinterleave6.v12f16(<12 x half> %v) @@ -782,38 +1028,35 @@ define {<2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>, <2 x half>} define {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @vector_deinterleave6_v12bf16_v2bf16(<12 x bfloat> %v) { ; CHECK-LABEL: vector_deinterleave6_v12bf16_v2bf16: ; CHECK: # %bb.0: -; CHECK-NEXT: addi sp, sp, -16 -; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi sp, sp, -32 +; CHECK-NEXT: .cfi_def_cfa_offset 32 +; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetivli zero, 2, e16, m2, ta, ma ; CHECK-NEXT: vslidedown.vi v10, v8, 10 ; CHECK-NEXT: vslidedown.vi v12, v8, 8 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) ; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma ; CHECK-NEXT: vslidedown.vi v9, v8, 6 -; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vslidedown.vi v13, v8, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v8, v13, a1 -; CHECK-NEXT: vslideup.vx v12, v10, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: vmv1r.v v9, v12 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: addi a1, sp, 28 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 24 +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 4 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 20 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 2, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 2 +; CHECK-NEXT: addi a1, sp, 16 +; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg6e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 -; CHECK-NEXT: addi sp, sp, 16 +; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>, <2 x bfloat>} @llvm.vector.deinterleave6.v12bf16(<12 x bfloat> %v) @@ -825,38 +1068,35 @@ define {<1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vmv1r.v v10, v8 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v10, v12, a1 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 5 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vslideup.vx v10, v11, a0 +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: vslidedown.vi v10, v8, 5 ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: vslideup.vx v11, v8, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v10, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg7e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -869,38 +1109,35 @@ define {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 +; CHECK-NEXT: addi a0, sp, 2 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vmv1r.v v10, v8 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vslideup.vx v10, v12, a1 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v9, v8, 5 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vslideup.vx v10, v11, a0 +; CHECK-NEXT: vslidedown.vi v9, v8, 6 +; CHECK-NEXT: vslidedown.vi v10, v8, 5 ; CHECK-NEXT: vslidedown.vi v11, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v9, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v8, v8, 6 -; CHECK-NEXT: vslideup.vx v11, v8, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v10, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg7e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -913,39 +1150,40 @@ define {<1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, <1 x half>, ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v10, v8, 7 -; CHECK-NEXT: vslidedown.vi v11, v8, 6 -; CHECK-NEXT: vslidedown.vi v12, v8, 5 -; CHECK-NEXT: vslidedown.vi v9, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v9, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v9, v11, a0 -; CHECK-NEXT: vslidedown.vi v10, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 7 +; CHECK-NEXT: vslidedown.vi v10, v8, 6 +; CHECK-NEXT: vslidedown.vi v11, v8, 5 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg8e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret @@ -958,45 +1196,43 @@ define {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 ; CHECK: # %bb.0: ; CHECK-NEXT: addi sp, sp, -16 ; CHECK-NEXT: .cfi_def_cfa_offset 16 -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: sub sp, sp, a0 -; CHECK-NEXT: .cfi_escape 0x0f, 0x0d, 0x72, 0x00, 0x11, 0x10, 0x22, 0x11, 0x02, 0x92, 0xa2, 0x38, 0x00, 0x1e, 0x22 # sp + 16 + 2 * vlenb -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: srli a1, a0, 3 ; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma -; CHECK-NEXT: vslidedown.vi v10, v8, 7 -; CHECK-NEXT: vslidedown.vi v11, v8, 6 -; CHECK-NEXT: vslidedown.vi v12, v8, 5 -; CHECK-NEXT: vslidedown.vi v9, v8, 4 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v9, v12, a1 -; CHECK-NEXT: srli a0, a0, 2 -; CHECK-NEXT: vsetvli a2, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v9, v11, a0 -; CHECK-NEXT: vslidedown.vi v10, v8, 3 -; CHECK-NEXT: vslidedown.vi v11, v8, 2 -; CHECK-NEXT: vslidedown.vi v12, v8, 1 -; CHECK-NEXT: vsetvli a2, zero, e16, mf2, ta, ma -; CHECK-NEXT: vslideup.vx v11, v10, a1 -; CHECK-NEXT: vslideup.vx v8, v12, a1 -; CHECK-NEXT: vsetvli a1, zero, e16, m1, ta, ma -; CHECK-NEXT: vslideup.vx v8, v11, a0 -; CHECK-NEXT: addi a0, sp, 16 -; CHECK-NEXT: vs2r.v v8, (a0) -; CHECK-NEXT: vsetvli a1, zero, e16, mf4, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 7 +; CHECK-NEXT: vslidedown.vi v10, v8, 6 +; CHECK-NEXT: vslidedown.vi v11, v8, 5 +; CHECK-NEXT: mv a0, sp +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v8, (a0) +; CHECK-NEXT: addi a1, sp, 14 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v12, v8, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: addi a1, sp, 12 +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v9, v8, 3 +; CHECK-NEXT: addi a1, sp, 10 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v11, (a1) +; CHECK-NEXT: addi a1, sp, 8 +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v10, v8, 2 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v12, (a1) +; CHECK-NEXT: addi a1, sp, 6 +; CHECK-NEXT: vse16.v v9, (a1) +; CHECK-NEXT: vsetivli zero, 1, e16, m1, ta, ma +; CHECK-NEXT: vslidedown.vi v8, v8, 1 +; CHECK-NEXT: addi a1, sp, 4 +; CHECK-NEXT: vsetivli zero, 1, e16, mf4, ta, ma +; CHECK-NEXT: vse16.v v10, (a1) +; CHECK-NEXT: addi a1, sp, 2 +; CHECK-NEXT: vse16.v v8, (a1) ; CHECK-NEXT: vlseg8e16.v v8, (a0) -; CHECK-NEXT: csrr a0, vlenb -; CHECK-NEXT: slli a0, a0, 1 -; CHECK-NEXT: add sp, sp, a0 -; CHECK-NEXT: .cfi_def_cfa sp, 16 ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: .cfi_def_cfa_offset 0 ; CHECK-NEXT: ret %res = call {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>} @llvm.vector.deinterleave8.v8bf16(<8 x bfloat> %v) ret {<1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>, <1 x bfloat>} %res } -;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -; RV32: {{.*}} -; RV64: {{.*}} From 1b5d76004bbdcadd3371fea901f36427d3f5303a Mon Sep 17 00:00:00 2001 From: Sirraide Date: Thu, 9 Jul 2026 22:00:31 +0200 Subject: [PATCH 015/125] [Clang] Fix crash involving `__attribute__((cleanup))` attributes and improve handling of multiple `cleanup` attributes (#207785) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clang would previously crash on this code: ```c #define C(x) __attribute__((cleanup(x))) void foo(double *x) {} void bar() { C(foo) C(foo) baz8; } ``` Here, we were trying to query properties of `VD->getType()`, which would crash because type of the variable declaration is null here (because the user didn’t write a type); avoid this by bailing out early if the declaration is invalid. Additionally, this patch fixes a GCC compatibility issue: in code such as ```c #define C(x) __attribute__((cleanup(x))) void f1(double *x); void f2(double *x); void bar() { C(f1) C(f2) double x; } ``` Clang would only use the first cleanup attribute, whereas GCC only uses the last one; I’ve changed our behaviour to match GCC’s and added a diagnostic that informs the user that only the last cleanup attribute is actually used. Fixes #191829. --- clang/docs/ReleaseNotes.md | 4 ++ .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/lib/Sema/SemaDeclAttr.cpp | 9 +++- clang/test/CodeGen/attr-cleanup-duplicate.c | 53 +++++++++++++++++++ clang/test/Sema/attr-cleanup-duplicate.c | 43 +++++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 clang/test/CodeGen/attr-cleanup-duplicate.c create mode 100644 clang/test/Sema/attr-cleanup-duplicate.c diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index dd63b4e5555d4..d974e99680800 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -799,6 +799,10 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - Fixed an assertion where we improperly handled implicit conversions to integral types from an atomic-type with a conversion function. (#GH201770) - Fixed assertion failures involving code completion with delayed default arguments and exception specifications. (#GH200879) - Fixed a regression where calling a function that takes a class-type parameter by value inside `decltype` of a concept could be incorrectly rejected when used as a non-type template argument. (#GH175831) +- Clang no longer crashes if `__attribute__((cleanup))` is applied to an invalid declaration. Furthermore, in declarations that + contain multiple `cleanup` attributes, Clang now only uses the last one, matching GCC's behaviour (previously, Clang + would only use the first one). A new warning that diagnoses such declarations has been added to `-Wignored-attributes`. + (#GH191829) - Fixed a crash in the constant evaluator when an ill-formed array new-expression whose bound could not be determined (e.g. `new int[]()`) was used in a constant expression. (#GH200139) - Clang now defines the GCC-compatible predefined macros `__WCHAR_MIN__`, `__WINT_MIN__`, and `__SIG_ATOMIC_MIN__`. (#GH199678) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fc5ee57cd855c..09a533ed7dd11 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4866,6 +4866,9 @@ def err_attribute_cleanup_func_must_take_one_arg : Error< def err_attribute_cleanup_func_arg_incompatible_type : Error< "'cleanup' function %0 parameter has " "%diff{type $ which is incompatible with type $|incompatible type}1,2">; +def warn_duplicate_cleanup_attr : Warning< + "declaration has multiple 'cleanup' attributes; all but the last one will be ignored">, + InGroup; def err_attribute_malloc_arg_not_function : Error< "'malloc' argument %select{for deallocator |%1 |%1 }0is not a %select{||single }0function">; def err_attribute_malloc_arg_not_function_with_pointer_arg : Error< diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 0d5b0f5fa2898..1b272b5416860 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3904,6 +3904,13 @@ static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } + // If a declaration contains multiple cleanup attributes, GCC only uses + // the last one. + if (const auto *A = D->getAttr()) { + S.Diag(A->getLoc(), diag::warn_duplicate_cleanup_attr) << A->getRange(); + D->dropAttr(); + } + auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD); attr->setArgLoc(E->getExprLoc()); D->addAttr(attr); @@ -9023,7 +9030,7 @@ void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) { void Sema::ActOnCleanupAttr(Decl *D, const Attr *A) { VarDecl *VD = cast(D); - if (VD->getType()->isDependentType()) + if (VD->isInvalidDecl() || VD->getType()->isDependentType()) return; // Obtains the FunctionDecl that was found when handling the attribute diff --git a/clang/test/CodeGen/attr-cleanup-duplicate.c b/clang/test/CodeGen/attr-cleanup-duplicate.c new file mode 100644 index 0000000000000..3bf5cccfee4d4 --- /dev/null +++ b/clang/test/CodeGen/attr-cleanup-duplicate.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-unknown-linux %s | FileCheck %s + +// Tests for issue #207785. + +void f1(double *x); +void f2(double *x); +void f3(double *x); + +// CHECK-LABEL: define {{.*}} void @g1() +void g1() { + // CHECK: call void @f3 + // CHECK-NOT: call void @f2 + // CHECK-NOT: call void @f1 + __attribute__((cleanup(f1))) + __attribute__((cleanup(f2))) + __attribute__((cleanup(f3))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g2() +void g2() { + // CHECK: call void @f1 + __attribute__((cleanup(f1))) + __attribute__((cleanup(f1))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g3() +void g3() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + __attribute__((cleanup(f2))) + __attribute__((cleanup(f1))) + double x; +} + +// CHECK-LABEL: define {{.*}} void @g4() +void g4() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + [[gnu::cleanup(f2)]] + [[gnu::cleanup(f1)]] + double x; +} + +// CHECK-LABEL: define {{.*}} void @g5() +void g5() { + // CHECK: call void @f1 + // CHECK-NOT: call void @f2 + [[gnu::cleanup(f2)]] + __attribute__((cleanup(f1))) + double x; +} diff --git a/clang/test/Sema/attr-cleanup-duplicate.c b/clang/test/Sema/attr-cleanup-duplicate.c new file mode 100644 index 0000000000000..ea596250b612a --- /dev/null +++ b/clang/test/Sema/attr-cleanup-duplicate.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +// Tests for issue #207785. +// +// Check that a cleanup attribute on an invalid declaration doesn't crash, +// and that we diagnose duplicate cleanup attributes. + +void f1(unsigned *x) {} +void b1() { + __attribute__((cleanup(f1))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f1))) // expected-error {{'cleanup' function 'f1' parameter has type 'unsigned int *' which is incompatible with type 'int *'}} + baz8; // expected-error {{type specifier missing, defaults to 'int'}} + +} + +void b2() { + __attribute__((cleanup(f1))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f1))) // expected-error {{'cleanup' function 'f1' parameter has type 'unsigned int *' which is incompatible with type 'int *'}} + int baz8; +} + +void f2(double *x); +void f3(double *x); +void f4(double *x); +void b3() { + __attribute__((cleanup(f2))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f3))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f4))) + double x; +} + +void b4() { + [[gnu::cleanup(f2)]] // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + [[gnu::cleanup(f3)]] + double x; +} + +void b5() { + [[gnu::cleanup(f2)]] // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f3))) // expected-warning {{declaration has multiple 'cleanup' attributes; all but the last one will be ignored}} + __attribute__((cleanup(f4))) + double x; +} From 766161cd2fbe851bf1a67abe469269057aa854de Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Thu, 9 Jul 2026 20:08:28 +0000 Subject: [PATCH 016/125] [scudo] Small refactor of getTSDXXX functions. (#208127) Small modification in getTSDAndLock() to have a single shared TSD avoid the tryLock call. Also, remove some unnecessary comments. Add a DCHECK in getTSDSlow and only check for == 1 since a 0 number of shared TSDs is not supported. --- compiler-rt/lib/scudo/standalone/tsd_shared.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/compiler-rt/lib/scudo/standalone/tsd_shared.h b/compiler-rt/lib/scudo/standalone/tsd_shared.h index 5f9092b36d42a..859f42eb373b2 100644 --- a/compiler-rt/lib/scudo/standalone/tsd_shared.h +++ b/compiler-rt/lib/scudo/standalone/tsd_shared.h @@ -141,16 +141,14 @@ struct TSDRegistrySharedT { ALWAYS_INLINE TSD *getTSDAndLock() NO_THREAD_SAFETY_ANALYSIS { TSD *TSD = getCurrentTSD(); DCHECK(TSD); - // Try to lock the currently associated context. - if (TSD->tryLock()) - return TSD; - // If that fails, go down the slow path. if (TSDsArraySize == 1U) { - // Only 1 TSD, not need to go any further. - // The compiler will optimize this one way or the other. + // Only 1 TSD, lock and return. TSD->lock(); return TSD; } + + if (TSD->tryLock()) + return TSD; return getTSDSlow(TSD); } @@ -176,6 +174,7 @@ struct TSDRegistrySharedT { // Requires a lock to avoid multiple threads trying to set the TSDs at once. bool setNumberOfTSDs(u32 N) REQUIRES(Mutex) { + DCHECK_GT(N, 0); const u32 TotalTSDs = atomic_load_relaxed(&NumberOfTSDs); // In order to avoid needing locks for these values, the number of TSDs // can never be decreased. @@ -234,7 +233,7 @@ struct TSDRegistrySharedT { // capability. NOINLINE TSD *getTSDSlow(TSD *CurrentTSD) { const u32 TotalTSDs = atomic_load_relaxed(&NumberOfTSDs); - if (UNLIKELY(TotalTSDs <= 1U)) { + if (UNLIKELY(TotalTSDs == 1U)) { CurrentTSD->lock(); return CurrentTSD; } From 720066abc2ee68efff28cc35c7e6ae40d3a9833f Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 9 Jul 2026 22:18:30 +0200 Subject: [PATCH 017/125] BPF: Fix misfolding subregisters (#208244) This would end up introducing a copy between registers with mismatched sizes previously. Defends against verifier failures in a future change. The actual transform here should be deleted. Optimizations should not be trying to introduce SUBREG_TO_REG. --- llvm/lib/Target/BPF/BPFMIPeephole.cpp | 6 ++- .../CodeGen/BPF/mov32-64-subreg-source.mir | 44 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp index c6fa0bf6d23bc..2adf4ea6fdfe7 100644 --- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp +++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp @@ -155,7 +155,11 @@ bool BPFMIPeephole::isInsnFrom32Def(MachineInstr *DefInsn) bool BPFMIPeephole::isMovFrom32Def(MachineInstr *MovMI) { - MachineInstr *DefInsn = MRI->getVRegDef(MovMI->getOperand(1).getReg()); + const MachineOperand &Src = MovMI->getOperand(1); + if (Src.getSubReg()) + return false; + + MachineInstr *DefInsn = MRI->getVRegDef(Src.getReg()); LLVM_DEBUG(dbgs() << " Def of Mov Src:"); LLVM_DEBUG(DefInsn->dump()); diff --git a/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir new file mode 100644 index 0000000000000..6a83fec35fba2 --- /dev/null +++ b/llvm/test/CodeGen/BPF/mov32-64-subreg-source.mir @@ -0,0 +1,44 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6 +# RUN: llc -mtriple=bpfel -mattr=+alu32 -run-pass=bpf-mi-zext-elim -verify-machineinstrs %s -o - | FileCheck %s +... + +# Make sure that folds of MOV_32_64 respect a subregister index on the +# source operand. + +--- +name: mov32_64_subreg_source_imm +tracksRegLiveness: true +body: | + bb.0: + liveins: $r1 + ; CHECK-LABEL: name: mov32_64_subreg_source_imm + ; CHECK: liveins: $r1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[LD_imm64_:%[0-9]+]]:gpr = LD_imm64 0 + ; CHECK-NEXT: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[LD_imm64_]].sub_32 + ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]] + ; CHECK-NEXT: RET implicit $r0 + %0:gpr = LD_imm64 0 + %1:gpr = MOV_32_64 %0.sub_32 + $r0 = COPY %1:gpr + RET implicit $r0 +... + +--- +name: mov32_64_subreg_source_copy +tracksRegLiveness: true +body: | + bb.0: + liveins: $r1 + ; CHECK-LABEL: name: mov32_64_subreg_source_copy + ; CHECK: liveins: $r1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $r1 + ; CHECK-NEXT: [[MOV_32_64_:%[0-9]+]]:gpr = MOV_32_64 [[COPY]].sub_32 + ; CHECK-NEXT: $r0 = COPY [[MOV_32_64_]] + ; CHECK-NEXT: RET implicit $r0 + %0:gpr = COPY $r1 + %1:gpr = MOV_32_64 %0.sub_32 + $r0 = COPY %1:gpr + RET implicit $r0 +... From 8bbb5a875cbc0a5bf6c43b60a7de680ea20715da Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Thu, 9 Jul 2026 20:32:25 +0000 Subject: [PATCH 018/125] [Github][TestingTools] Build on multiple platforms Given we are shipping binaries, the produced packages are arch-specific so we need to build/cross-compile on all the architectures that we care about. Start by getting things working on latest MacOS and Windows. Reviewers: Michael137, ldionne Pull Request: https://github.com/llvm/llvm-project/pull/190884 --- .github/workflows/release-llvm-testing-tools.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-llvm-testing-tools.yml b/.github/workflows/release-llvm-testing-tools.yml index 7910b23a6b853..ecbec7c3891cc 100644 --- a/.github/workflows/release-llvm-testing-tools.yml +++ b/.github/workflows/release-llvm-testing-tools.yml @@ -12,7 +12,10 @@ on: jobs: build-package: name: Build Package - runs-on: ubuntu-24.04 + strategy: + matrix: + os: [ubuntu-24.04, windows-2025, macos-26] + runs-on: ${{ matrix.os }} if: github.repository == 'llvm/llvm-project' steps: - name: Fetch LLVM sources @@ -23,14 +26,12 @@ jobs: run: | mkdir build cd build - cmake -GNinja \ - -DCMAKE_BUILD_TYPE=Release \ - ../llvm + cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm ninja split-file FileCheck - name: Build Package + shell: bash run: | - sudo apt-get update - sudo apt-get install -y python3-build + pip3 install --break-system-packages build==1.4.2 cd ./llvm/utils/llvm-testing-tools mkdir ./src/llvm_testing_tools/binaries cp ../../../build/bin/FileCheck ./src/llvm_testing_tools/binaries/FileCheck @@ -39,5 +40,5 @@ jobs: - name: Upload Packages uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: packages + name: packages-${{ matrix.os }} path: ./llvm/utils/llvm-testing-tools/dist/* From c050a2c677879ab2b53dba4424a1ec814e89314a Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Thu, 9 Jul 2026 22:45:47 +0200 Subject: [PATCH 019/125] Revert "[lldb][Windows][CI] split steps (#206946)" (#208519) This reverts commit 07d5e0d550985db270e65131add93f8c5fda54dd. --- .ci/green-dragon/lldb-windows.groovy | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/.ci/green-dragon/lldb-windows.groovy b/.ci/green-dragon/lldb-windows.groovy index 569932fb0ff92..bec44d39f8961 100644 --- a/.ci/green-dragon/lldb-windows.groovy +++ b/.ci/green-dragon/lldb-windows.groovy @@ -48,7 +48,7 @@ pipeline { } } - stage('Build and Test (No LLDB Server)') { + stage('Build and Test') { steps { timeout(60) { catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { @@ -81,28 +81,6 @@ cmake -G Ninja ^ -DLLVM_LIT_ARGS="-v --time-tests --xunit-xml-output=C:\\workspace\\llvm-build\\test\\results-no-lldb-server.xml" ^ -DPython3_EXECUTABLE="C:\\Program Files\\Python313\\python.exe" || exit /b 1 ninja check-lldb -C ..\\llvm-build || exit /b 1 -''' - bat ''' - docker run --rm ^ - -e BUILD_TYPE=%BUILD_TYPE% ^ - -v "%CD%:C:\\workspace" ^ - -w "C:\\workspace\\llvm-project" ^ - swiftlang/swift-ci:lldb-windowsservercore-1809 ^ - cmd /C C:\\workspace\\build.bat - ''' - } - } - } - } - - stage('Test (LLDB Server)') { - steps { - timeout(30) { - catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { - writeFile file: 'test-lldb-server.bat', text: '''@echo off -call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat" || exit /b 1 - -set "PATH=%PATH%;C:\\Program Files\\Git\\usr\\bin" cmake -G Ninja ^ -S llvm ^ @@ -117,12 +95,13 @@ ninja check-lldb -C ..\\llvm-build || exit /b 1 -v "%CD%:C:\\workspace" ^ -w "C:\\workspace\\llvm-project" ^ swiftlang/swift-ci:lldb-windowsservercore-1809 ^ - cmd /C C:\\workspace\\test-lldb-server.bat + cmd /C C:\\workspace\\build.bat ''' } } } } + } post { always { From a1609094a014e13db33796a45e46c96e94561e78 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Thu, 9 Jul 2026 16:48:26 -0400 Subject: [PATCH 020/125] [SystemZ][z/OS] Honor alignment of global data (#208095) The alignment of sections is set after the section are created. Thus, the ED structure set at object construction time is updated with the current section alignment. This only applies to ED type section. As result, the alignment of global data is correctly set. Assisted by: IBM Bob --- llvm/include/llvm/MC/MCGOFFAttributes.h | 1 - llvm/include/llvm/MC/MCSectionGOFF.h | 13 +++++++-- .../CodeGen/TargetLoweringObjectFileImpl.cpp | 10 +++---- llvm/lib/MC/GOFFObjectWriter.cpp | 16 ++++++----- llvm/lib/MC/MCAsmInfoGOFF.cpp | 10 +++---- llvm/lib/MC/MCObjectFileInfo.cpp | 20 ++++++------- llvm/test/CodeGen/SystemZ/zos-align.ll | 28 +++++++++++++++++++ llvm/test/CodeGen/SystemZ/zos-section-1.ll | 2 +- 8 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 llvm/test/CodeGen/SystemZ/zos-align.ll diff --git a/llvm/include/llvm/MC/MCGOFFAttributes.h b/llvm/include/llvm/MC/MCGOFFAttributes.h index 9787ef4c916a9..289d962e993b8 100644 --- a/llvm/include/llvm/MC/MCGOFFAttributes.h +++ b/llvm/include/llvm/MC/MCGOFFAttributes.h @@ -57,7 +57,6 @@ struct EDAttr { GOFF::ESDBindingAlgorithm BindAlgorithm = GOFF::ESD_BA_Concatenate; GOFF::ESDLoadingBehavior LoadBehavior = GOFF::ESD_LB_Initial; GOFF::ESDReserveQwords ReservedQwords = GOFF::ESD_RQ_0; - GOFF::ESDAlignment Alignment = GOFF::ESD_ALIGN_Doubleword; uint8_t FillByteValue = 0; }; diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h index 288f9038bb65e..6351a1e3dc933 100644 --- a/llvm/include/llvm/MC/MCSectionGOFF.h +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -19,8 +19,6 @@ #include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSection.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" namespace llvm { @@ -98,6 +96,17 @@ class LLVM_ABI MCSectionGOFF final : public MCSection { assert(isED() && "Not a ED section"); return EDAttributes; } + + // Returns the ESD alignment value for the ED section, computed from the + // MCSection alignment. Only defined for ED sections. + GOFF::ESDAlignment getEDAlignment() const { + assert(isED() && "Not a ED section"); + uint8_t Log = Log2(getAlign()); + if (Log > GOFF::ESD_ALIGN_4Kpage) + reportFatalUsageError("Unsupported alignment"); + return static_cast(Log); + } + GOFF::PRAttr getPRAttributes() const { assert(isPR() && "Not a PR section"); return PRAttributes; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index f983c3205f927..174e7b088ca4b 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2865,9 +2865,9 @@ MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Fullword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, static_cast(TextSection)->getParent()); + WSA->setAlignment(Align(4)); // Fullword return getContext().getGOFFSection(SectionKind::getData(), Name, GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, @@ -2893,9 +2893,6 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( Alignment = F->getAlign(); else if (auto *V = dyn_cast(GO)) Alignment = V->getAlign(); - GOFF::ESDAlignment Align = - Alignment ? static_cast(Log2(*Alignment)) - : GOFF::ESD_ALIGN_Doubleword; MCSectionGOFF *SD = getContext().getGOFFSection( SectionKind::getMetadata(), Symbol->getName(), GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}); @@ -2903,8 +2900,9 @@ MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0}, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, 0}, SD); + ED->setAlignment(Alignment.value_or(llvm::Align(8))); return getContext().getGOFFSection(Kind, Symbol->getName(), GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, diff --git a/llvm/lib/MC/GOFFObjectWriter.cpp b/llvm/lib/MC/GOFFObjectWriter.cpp index 4d23746775df1..ab497ac38b90e 100644 --- a/llvm/lib/MC/GOFFObjectWriter.cpp +++ b/llvm/lib/MC/GOFFObjectWriter.cpp @@ -229,7 +229,7 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const GOFF::EDAttr &Attr) + const GOFF::EDAttr &Attr, GOFF::ESDAlignment Alignment) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_ElementDefinition) { this->NameSpace = Attr.NameSpace; @@ -243,7 +243,7 @@ class GOFFSymbol { BehavAttrs.setTextStyle(Attr.TextStyle); BehavAttrs.setBindingAlgorithm(Attr.BindAlgorithm); BehavAttrs.setLoadingBehavior(Attr.LoadBehavior); - BehavAttrs.setAlignment(Attr.Alignment); + BehavAttrs.setAlignment(Alignment); } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, @@ -259,14 +259,15 @@ class GOFFSymbol { } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, - const GOFF::EDAttr &EDAttr, const GOFF::PRAttr &Attr) + const GOFF::EDAttr &EDAttr, GOFF::ESDAlignment Alignment, + const GOFF::PRAttr &Attr) : Name(Name.data(), Name.size()), EsdId(EsdID), ParentEsdId(ParentEsdID), SymbolType(GOFF::ESD_ST_PartReference), NameSpace(EDAttr.NameSpace) { SymbolFlags.setRenameable(Attr.IsRenamable); BehavAttrs.setExecutable(Attr.Executable); BehavAttrs.setLinkageType(Attr.Linkage); BehavAttrs.setBindingScope(Attr.BindingScope); - BehavAttrs.setAlignment(EDAttr.Alignment); + BehavAttrs.setAlignment(Alignment); } GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID, @@ -323,7 +324,8 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { if (Section.isED()) { GOFFSymbol ED(Section.getExternalName(), Section.getOrdinal(), - Section.getParent()->getOrdinal(), Section.getEDAttributes()); + Section.getParent()->getOrdinal(), Section.getEDAttributes(), + Section.getEDAlignment()); ED.SectionLength = Asm.getSectionAddressSize(Section); writeSymbol(ED); } @@ -332,7 +334,7 @@ void GOFFWriter::defineSectionSymbols(const MCSectionGOFF &Section) { MCSectionGOFF *Parent = Section.getParent(); GOFFSymbol PR(Section.getExternalName(), Section.getOrdinal(), Parent->getOrdinal(), Parent->getEDAttributes(), - Section.getPRAttributes()); + Parent->getEDAlignment(), Section.getPRAttributes()); PR.SectionLength = Asm.getSectionAddressSize(Section); if (Section.requiresNonZeroLength()) { // We cannot have a zero-length section for data. If we do, @@ -364,7 +366,7 @@ void GOFFWriter::defineExtern(const MCSymbolGOFF &Symbol) { if (Symbol.getCodeData() == GOFF::ESD_EXE_DATA) { MCSectionGOFF *ED = Symbol.getADA()->getParent(); GOFFSymbol PR(Symbol.getExternalName(), Symbol.getIndex(), ED->getOrdinal(), - ED->getEDAttributes(), + ED->getEDAttributes(), ED->getEDAlignment(), GOFF::PRAttr{/*IsRenamable*/ false, Symbol.getCodeData(), Symbol.getLinkage(), Symbol.getBindingScope(), 0}); diff --git a/llvm/lib/MC/MCAsmInfoGOFF.cpp b/llvm/lib/MC/MCAsmInfoGOFF.cpp index 97063099597da..c644e599bfb26 100644 --- a/llvm/lib/MC/MCAsmInfoGOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoGOFF.cpp @@ -140,10 +140,10 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section, case GOFF::ESD_ST_ElementDefinition: { printSwitchToSection(*Sec.getParent(), Subsection, T, OS); if (!Sec.Emitted) { - emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode, - Sec.EDAttributes.Alignment, Sec.EDAttributes.LoadBehavior, - GOFF::ESD_EXE_Unspecified, Sec.EDAttributes.IsReadOnly, 0, - Sec.EDAttributes.FillByteValue, StringRef()); + emitCATTR(OS, Sec.getName(), Sec.EDAttributes.Rmode, Sec.getEDAlignment(), + Sec.EDAttributes.LoadBehavior, GOFF::ESD_EXE_Unspecified, + Sec.EDAttributes.IsReadOnly, 0, Sec.EDAttributes.FillByteValue, + StringRef()); if (auto *BeginSym = static_cast(Sec.getBeginSymbol())) { if (BeginSym->getADA()) emitXATTR(OS, BeginSym->getName(), BeginSym->getADA(), @@ -161,7 +161,7 @@ void MCAsmInfoGOFF::printSwitchToSection(const MCSection &Section, printSwitchToSection(*ED->getParent(), Subsection, T, OS); if (!Sec.Emitted) { emitCATTR(OS, ED->getName(), ED->getEDAttributes().Rmode, - ED->EDAttributes.Alignment, ED->EDAttributes.LoadBehavior, + ED->getEDAlignment(), ED->EDAttributes.LoadBehavior, Sec.PRAttributes.Executable, ED->EDAttributes.IsReadOnly, Sec.PRAttributes.SortKey, ED->EDAttributes.FillByteValue, Sec.getName()); diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index b4b660c104868..2ac01cf4b84de 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -587,9 +587,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getMetadata(), GOFF::CLASS_WSA, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, - GOFF::ESD_ALIGN_Quadword, 0}, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_1, 0}, RootSDSection); + ADAEDSection->setAlignment(Align(16)); // Quadword ADASection = Ctx->getGOFFSection(SectionKind::getData(), "#S", GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_XPLink, @@ -600,17 +600,17 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getText(), GOFF::CLASS_CODE, GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_NormalName, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, RootSDSection); + TextSection->setAlignment(Align(8)); // Doubleword MCSectionGOFF *PPA2ListEDSection = Ctx->getGOFFSection( SectionKind::getMetadata(), GOFF::CLASS_PPA2, GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, - GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, 0}, RootSDSection); + PPA2ListEDSection->setAlignment(Align(8)); // Doubleword PPA2ListSection = Ctx->getGOFFSection(SectionKind::getData(), ".&ppa2", GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, GOFF::ESD_LT_OS, @@ -621,9 +621,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getData(), "B_IDRL", GOFF::EDAttr{true, GOFF::ESD_RMODE_64, GOFF::ESD_NS_NormalName, GOFF::ESD_TS_Structured, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, 0}, RootSDSection); + IDRLSection->setAlignment(Align(8)); // Doubleword // Debug Info Sections. The ED name is the same used by the XL compiler. auto InitDebugSection = [this, @@ -633,9 +633,9 @@ void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) { SectionKind::getMetadata(), EDName, GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Concatenate, - GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, - GOFF::ESD_ALIGN_Doubleword, 0}, + GOFF::ESD_LB_NoLoad, GOFF::ESD_RQ_0, 0}, RootSDSection); + ED->setAlignment(Align(8)); // Doubleword // At least for llc, this function is called twice! (See function // compileModule() in llc.cpp). Since the context is not cleared, the // already allocated section is returned above. We only add the begin symbol diff --git a/llvm/test/CodeGen/SystemZ/zos-align.ll b/llvm/test/CodeGen/SystemZ/zos-align.ll new file mode 100644 index 0000000000000..59827dec16079 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/zos-align.ll @@ -0,0 +1,28 @@ +; Test alignment of global constants +; +; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 | FileCheck %s + +@data = global [8 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7], align 4096 + +; CHECK: * @data +; CHECK-NEXT: data CSECT +; CHECK-NEXT: C_WSA64 CATTR ALIGN(12),FILL(0),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(dat +; CHECK-NEXT: ta) +; CHECK-NEXT: data XATTR LINKAGE(XPLINK),REFERENCE(DATA),SCOPE(EXPORT) +; CHECK-NEXT: DS 0B +; CHECK-NEXT: * 0x0 +; CHECK-NEXT: DC XL4'00000000' +; CHECK-NEXT: * 0x1 +; CHECK-NEXT: DC XL4'00000001' +; CHECK-NEXT: * 0x2 +; CHECK-NEXT: DC XL4'00000002' +; CHECK-NEXT: * 0x3 +; CHECK-NEXT: DC XL4'00000003' +; CHECK-NEXT: * 0x4 +; CHECK-NEXT: DC XL4'00000004' +; CHECK-NEXT: * 0x5 +; CHECK-NEXT: DC XL4'00000005' +; CHECK-NEXT: * 0x6 +; CHECK-NEXT: DC XL4'00000006' +; CHECK-NEXT: * 0x7 +; CHECK-NEXT: DC XL4'00000007' diff --git a/llvm/test/CodeGen/SystemZ/zos-section-1.ll b/llvm/test/CodeGen/SystemZ/zos-section-1.ll index c5020fcb9f24a..f4b9667d5d915 100644 --- a/llvm/test/CodeGen/SystemZ/zos-section-1.ll +++ b/llvm/test/CodeGen/SystemZ/zos-section-1.ll @@ -46,7 +46,7 @@ entry: ; CHECK-NEXT: 0000b0 00 00 00 00 00 00 00 00 00 00 00 {{..}} 00 00 00 00 ; CHECK-NEXT: 0000c0 00 00 00 00 00 00 00 00 01 80 00 00 00 00 00 00 ; CHECK-NEXT: 0000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 08 -; CHECK-NEXT: 0000e0 00 00 03 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4 +; CHECK-NEXT: 0000e0 00 00 04 00 00 00 00 08 c3 6d c3 d6 c4 c5 f6 f4 ; ESD record, type ED. ; The name is C_@@QPPA2. From 0f9f5a2aba97070971f2d58f2e307f621edf9ada Mon Sep 17 00:00:00 2001 From: Maryam Moghadas Date: Thu, 9 Jul 2026 16:53:18 -0400 Subject: [PATCH 021/125] [z/OS][Clang] Add compare and swap builtin functions (#202362) Implements the following compare and swap builtins: ``` int __cs(unsigned int *, unsigned int *, unsigned int), 4 byte compare & swap int __cs1(void* OP1, void* OP2, void* OP3), 4 byte compare & swap int __csg(void* OP1, void* OP2, void* OP3), 8 byte compare & swap int __cds1(void* OP1, void* OP2, void* OP3), 8 byte compare & swap int __cdsg(void* OP1, void* OP2, void* OP3), 16 byte compare & swap ``` The implementation utilizes the llvm cmpxchg intrinsic to generate the CS instructions, then it generates a store instruction to store OP2 into OP1, and finally invert the success flag of cmpxchg by an XOR instruction with 1 and return the flag. --- clang/docs/LanguageExtensions.md | 34 +++++++++ clang/include/clang/Basic/BuiltinsZOS.td | 27 ++++++++ clang/include/clang/Basic/CMakeLists.txt | 4 ++ clang/include/clang/Basic/TargetBuiltins.h | 13 ++-- clang/lib/Basic/Targets/SystemZ.cpp | 22 +++++- clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp | 69 +++++++++++++++++-- clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/zos_wrappers/stdlib.h | 20 ++++++ clang/test/CodeGen/SystemZ/builtins-zos-cs.c | 66 ++++++++++++++++++ .../Headers/Inputs/zos/usr/include/stdlib.h | 3 + clang/test/Headers/zos-cs-wrapper.c | 13 ++++ 11 files changed, 263 insertions(+), 9 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsZOS.td create mode 100644 clang/lib/Headers/zos_wrappers/stdlib.h create mode 100644 clang/test/CodeGen/SystemZ/builtins-zos-cs.c create mode 100644 clang/test/Headers/Inputs/zos/usr/include/stdlib.h create mode 100644 clang/test/Headers/zos-cs-wrapper.c diff --git a/clang/docs/LanguageExtensions.md b/clang/docs/LanguageExtensions.md index 68416e801bd5d..c0b921d058777 100644 --- a/clang/docs/LanguageExtensions.md +++ b/clang/docs/LanguageExtensions.md @@ -5538,6 +5538,40 @@ int a = 1; __builtin_dcbf (&a); ``` +### z/OS Language Extensions + +#### z/OS builtins + +z/OS supports builtins for compare-and-swap operations that generate the +corresponding z/OS assembly instructions (CS, CSG, CDSG). These builtins compare +the value pointed to by oldptr to the value pointed to by curptr. If they are +equal, the value pointed to by newword (or newword itself for `__cs`) is +copied into the location pointed to by curptr. If they are unequal, the value +pointed to by curptr is copied into the location pointed to by oldptr. +The builtins return 0 if the values are equal, or 1 if they are unequal. + +- `int __cs(unsigned int *oldptr, unsigned int *curptr, unsigned int newword)` + + Generates a 4-byte compare-and-swap using the CS instruction. + Use `__cs` instead of `__cs1` when the newword arg is an r-value instead + of an l-value. + +- `int __cs1(void *oldptr, void *curptr, void *newword)` + + Generates a 4-byte compare-and-swap using the CS instruction. + +- `int __csg(void *oldptr, void *curptr, void *newword)` + + Generates an 8-byte compare-and-swap using the CSG instruction. + +- `int __cds1(void *oldptr, void *curptr, void *newword)` + + Generates an 8-byte compare-and-swap using the CSG instruction. + +- `int __cdsg(void *oldptr, void *curptr, void *newword)` + + Generates a 16-byte compare-and-swap using the CDSG instruction. + ## Extensions for Static Analysis Clang supports additional attributes that are useful for documenting program diff --git a/clang/include/clang/Basic/BuiltinsZOS.td b/clang/include/clang/Basic/BuiltinsZOS.td new file mode 100644 index 0000000000000..2089518fd18a8 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsZOS.td @@ -0,0 +1,27 @@ +//===-- BuiltinsZOS.td - z/OS Builtin function database ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the z/OS-specific builtin function database. +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class SystemZNoPrefixBuiltin : Builtin { + let Spellings = [NAME]; + let Prototype = prototype; +} + +// compare and swap functions +let Attributes = [NoThrow] in { + def __cs : SystemZNoPrefixBuiltin<"int(unsigned int *, unsigned int *, unsigned int)">; + def __cs1 : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __csg : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __cds1 : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; + def __cdsg : SystemZNoPrefixBuiltin<"int(void *, void *, void *)">; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index d90d326027583..d334c1d41e475 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -146,6 +146,10 @@ clang_tablegen(BuiltinsX86_64.inc -gen-clang-builtins SOURCE BuiltinsX86_64.td TARGET ClangBuiltinsX86_64) +clang_tablegen(BuiltinsZOS.inc -gen-clang-builtins + SOURCE BuiltinsZOS.td + TARGET ClangBuiltinsZOS) + clang_tablegen(BuiltinTemplates.inc -gen-clang-builtin-templates SOURCE BuiltinTemplates.td TARGET ClangBuiltinTemplates) diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 8cf8720f74573..5828aae483026 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -457,13 +457,18 @@ namespace clang { /// SystemZ builtins namespace SystemZ { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, #define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsSystemZ.inc" #undef GET_BUILTIN_ENUMERATORS - LastTSBuiltin - }; + FirstZOSBuiltin, + LastSystemZBuiltin = FirstZOSBuiltin - 1, +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_ENUMERATORS + LastTSBuiltin + }; } /// WebAssembly builtins diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp index 750629ac94f87..080a961b95d0d 100644 --- a/clang/lib/Basic/Targets/SystemZ.cpp +++ b/clang/lib/Basic/Targets/SystemZ.cpp @@ -22,7 +22,9 @@ using namespace clang; using namespace clang::targets; static constexpr int NumBuiltins = - clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin; + clang::SystemZ::LastSystemZBuiltin - Builtin::FirstTSBuiltin + 1; +static constexpr int NumBuiltinsZOS = + clang::SystemZ::LastTSBuiltin - clang::SystemZ::LastSystemZBuiltin - 1; #define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsSystemZ.inc" @@ -41,6 +43,20 @@ static constexpr Builtin::Info PrefixedBuiltinInfos[] = { }; static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == NumBuiltins); +namespace clang { +namespace ZOS { +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsZOS.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert((std::size(BuiltinInfos)) == NumBuiltinsZOS); +} // namespace ZOS +} // namespace clang const char *const SystemZTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -216,6 +232,10 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, llvm::SmallVector SystemZTargetInfo::getTargetBuiltins() const { + if (getTriple().isOSzOS()) + return {{&BuiltinStrings, BuiltinInfos}, + {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_s390_"}, + {&ZOS::BuiltinStrings, ZOS::BuiltinInfos}}; return {{&BuiltinStrings, BuiltinInfos}, {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_s390_"}}; } diff --git a/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp b/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp index c33d7581f50b8..2f8a5e62d6e9f 100644 --- a/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/SystemZ.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "CGBuiltin.h" #include "CodeGenFunction.h" #include "clang/Basic/TargetBuiltins.h" #include "llvm/IR/IntrinsicsS390.h" @@ -36,6 +37,52 @@ static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, return CGF.Builder.CreateExtractValue(Call, 0); } +/// For z/OS, the builtin __cs1 has the following signature: +/// int __cs1(void * Comparand, +/// void * Destination, +/// void * Exchange); +/// Whereas the llvm 'cmpxchg' instruction has the following syntax: +/// compxchg *Destination, Comparand, Exchange. +/// So we need to swap Comparand & Destination and dereference Comparand & +/// Exchange when invoking CreateAtomicCmpXchg. For this reason we can not use +/// the utility function MakeAtomicCmpXchgValue. +static Value *EmitAtomicCmpXchgForZOSIntrin(CodeGenFunction &CGF, + const CallExpr *E, + llvm::Type *IntType, bool HasAddr) { + + CharUnits Alignment = + CGF.getContext().toCharUnitsFromBits(IntType->getScalarSizeInBits()); + llvm::Value *ComparandPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *DestinationPtr = CGF.EmitScalarExpr(E->getArg(1)); + + Address DestinationAddr = Address(DestinationPtr, IntType, Alignment); + Address ComparandAddr = Address(ComparandPtr, IntType, Alignment); + + llvm::Value *Comparand = CGF.Builder.CreateLoad(ComparandAddr); + llvm::Value *Exchange; + if (HasAddr) { + llvm::Value *ExchangePtr = CGF.EmitScalarExpr(E->getArg(2)); + Address ExchangeAddr = Address(ExchangePtr, IntType, Alignment); + Exchange = CGF.Builder.CreateLoad(ExchangeAddr); + } else { + Exchange = CGF.EmitScalarExpr(E->getArg(2)); + } + + Value *Result = CGF.Builder.CreateAtomicCmpXchg( + DestinationAddr, Comparand, Exchange, + llvm::AtomicOrdering::SequentiallyConsistent, + llvm::AtomicOrdering::SequentiallyConsistent); + + // Store Destination in Comparand. + CGF.Builder.CreateStore(CGF.Builder.CreateExtractValue(Result, 0), + ComparandAddr); + + // Extract boolean success flag, invert it and zext it to int. + llvm::Value *RetVal = + CGF.Builder.CreateNot(CGF.Builder.CreateExtractValue(Result, 1)); + return CGF.Builder.CreateZExt(RetVal, CGF.ConvertType(E->getType())); +} + Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { switch (BuiltinID) { @@ -68,11 +115,25 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, Function *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); return Builder.CreateCall(F, {Data, Address}); } + case SystemZ::BI__cs: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int32Ty, false); + } + case SystemZ::BI__cs1: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int32Ty, true); + } + case SystemZ::BI__csg: + case SystemZ::BI__cds1: { + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int64Ty, true); + } + case SystemZ::BI__cdsg: { + llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); + return EmitAtomicCmpXchgForZOSIntrin(*this, E, Int128Ty, true); + } - // Vector builtins. Note that most vector builtins are mapped automatically - // to target-specific LLVM intrinsics. The ones handled specially here can - // be represented via standard LLVM IR, which is preferable to enable common - // LLVM optimizations. + // Vector builtins. Note that most vector builtins are mapped automatically + // to target-specific LLVM intrinsics. The ones handled specially here can + // be represented via standard LLVM IR, which is preferable to enable common + // LLVM optimizations. case SystemZ::BI__builtin_s390_vclzb: case SystemZ::BI__builtin_s390_vclzh: diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 4bbfb9ba1662a..b1d1832a598d9 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -415,6 +415,7 @@ set(zos_wrapper_files zos_wrappers/locale.h zos_wrappers/math.h zos_wrappers/poll.h + zos_wrappers/stdlib.h zos_wrappers/string.h zos_wrappers/time.h zos_wrappers/variant.h diff --git a/clang/lib/Headers/zos_wrappers/stdlib.h b/clang/lib/Headers/zos_wrappers/stdlib.h new file mode 100644 index 0000000000000..433e1b5ad0b23 --- /dev/null +++ b/clang/lib/Headers/zos_wrappers/stdlib.h @@ -0,0 +1,20 @@ +/*===----------------------------- stdlib.h --------------------------------=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +#ifndef __ZOS_WRAPPERS_STDLIB_H +#define __ZOS_WRAPPERS_STDLIB_H +#if __has_include_next() +#include_next +#ifdef _EXT +#ifndef __CS1 +#undef __cs +#endif +#endif /* _EXT */ +#endif /* __has_include_next() */ +#endif /* __ZOS_WRAPPERS_STDLIB_H */ diff --git a/clang/test/CodeGen/SystemZ/builtins-zos-cs.c b/clang/test/CodeGen/SystemZ/builtins-zos-cs.c new file mode 100644 index 0000000000000..d31bb537f210a --- /dev/null +++ b/clang/test/CodeGen/SystemZ/builtins-zos-cs.c @@ -0,0 +1,66 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -triple s390x-none-zos %s -emit-llvm -o - | FileCheck -check-prefix=CHECK %s +// RUN: %clang_cc1 -triple s390x-linux-gnu %s -verify + +int test_cs(unsigned int *a, unsigned int *b, unsigned int c) { + return __cs(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cs'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cs +// CHECK: cmpxchg ptr {{.*}}, i32 {{.*}}, i32 {{.*}} seq_cst seq_cst, align 4 +// CHECK: store i32 {{.*}}, ptr {{.*}}, align 4 +// CHECK: xor i1 {{.*}}, true + +int test_cs1(int *a, int *b, int *c) { + return __cs1(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cs1'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cs1 +// CHECK: cmpxchg ptr {{.*}}, i32 {{.*}}, i32 {{.*}} seq_cst seq_cst, align 4 +// CHECK: store i32 {{.*}}, ptr {{.*}}, align 4 +// CHECK: xor i1 {{.*}}, true + +typedef struct __attribute__((__aligned__(8))) { + int a; + int b; +} double_word; + +int test_cds1(double_word *a, double_word *b, double_word *c) { + return __cds1(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cds1'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cds1 +// CHECK: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst, align 8 +// CHECK: store i64 {{.*}}, ptr {{.*}}, align 8 +// CHECK: xor i1 {{.*}}, true + +typedef struct __attribute__((__aligned__(16))) { + int a; + int b; + int c; + int d; +} quadruple_word; + +int test_cdsg(quadruple_word *a, quadruple_word *b, quadruple_word *c) { + return __cdsg(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__cdsg'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_cdsg +// CHECK: cmpxchg ptr {{.*}}, i128 {{.*}}, i128 {{.*}} seq_cst seq_cst, align 16 +// CHECK: store i128 {{.*}}, ptr {{.*}}, align 16 +// CHECK: xor i1 {{.*}}, true + + +int test_csg(double_word *a, double_word *b, double_word *c) { + return __csg(a, b, c); +} +// expected-error@-2 {{call to undeclared function '__csg'; ISO C99 and later do not support implicit function declarations}} + +// CHECK-LABEL: define{{.*}} @test_csg +// CHECK: cmpxchg ptr {{.*}}, i64 {{.*}}, i64 {{.*}} seq_cst seq_cst, align 8 +// CHECK: store i64 {{.*}}, ptr {{.*}}, align 8 +// CHECK: xor i1 {{.*}}, true diff --git a/clang/test/Headers/Inputs/zos/usr/include/stdlib.h b/clang/test/Headers/Inputs/zos/usr/include/stdlib.h new file mode 100644 index 0000000000000..30ccbdfebdada --- /dev/null +++ b/clang/test/Headers/Inputs/zos/usr/include/stdlib.h @@ -0,0 +1,3 @@ +#ifdef _EXT +#define __cs(x, y, z) __cs1(x, y, &(z)) +#endif diff --git a/clang/test/Headers/zos-cs-wrapper.c b/clang/test/Headers/zos-cs-wrapper.c new file mode 100644 index 0000000000000..03b30b0f8ddbd --- /dev/null +++ b/clang/test/Headers/zos-cs-wrapper.c @@ -0,0 +1,13 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang -E --target=s390x-ibm-zos %s -mzos-sys-include=%S/Inputs/zos/usr/include | FileCheck %s --check-prefix=NOCS1 +// RUN: %clang -E --target=s390x-ibm-zos -D__CS1 %s -mzos-sys-include=%S/Inputs/zos/usr/include | FileCheck %s --check-prefix=CS1 + +#define _EXT +#include + +int func(unsigned int *a, unsigned int *b, unsigned int c) { + return __cs(a, b, c); +} + +// NOCS1: return __cs(a, b, c); +// CS1: return __cs1(a, b, &(c)); From 509a0b82038d04656eb4c0f172bb8199352b90e9 Mon Sep 17 00:00:00 2001 From: Lucas Chollet Date: Thu, 9 Jul 2026 23:11:06 +0200 Subject: [PATCH 022/125] [RISCV] Support Zdinx registers in -fzero-call-used-regs (#206323) First, this patch makes the backend consider GPRF16 and GPRF32 registers as GPR. These registers are aliases of normal GPR but for use with the Zdinx extension (floating points instructions on GPR). Second, it teaches the general -fzero-call-used-regs logic to handle used registers that span over multiple physical registers. One example of this is `GPRPair` in the RISC-V backend. --- llvm/lib/CodeGen/PrologEpilogInserter.cpp | 7 ++- llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 28 +++++++++- llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 6 +- .../test/CodeGen/RISCV/zero-call-used-regs.ll | 55 +++++++++++++++++++ 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp index 54a77524add94..43c7e89113b26 100644 --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -1278,8 +1278,11 @@ void PEIImpl::insertZeroCallUsedRegs(MachineFunction &MF) { // Want only registers used for arguments. if (OnlyArg) { if (OnlyUsed) { - if (!LiveIns[Reg.id()]) - continue; + for (MCRegister LiveReg : LiveIns.set_bits()) { + if (TRI.regsOverlap(Reg, LiveReg)) + RegsToZero.set(LiveReg); + } + continue; } else if (!TRI.isArgumentRegister(MF, Reg)) { continue; } diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp index 5672ec9f9a4de..bbd1738cd5117 100644 --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -1433,6 +1433,27 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF, emitSiFiveCLICStackSwap(MF, MBB, MBBI, DL); } +static MCRegister getPhysicalGPR(const TargetRegisterInfo &TRI, + MCRegister Reg) { + if (RISCV::GPRRegClass.contains(Reg)) + return Reg; + + std::array RegisterClasses = { + &RISCV::GPRF16RegClass, &RISCV::GPRF32RegClass}; + std::array SubIdx = {RISCV::sub_16, RISCV::sub_32}; + + for (auto [RegClass, SubReg] : zip(RegisterClasses, SubIdx)) { + if (RegClass->contains(Reg)) { + if (MCRegister Super = + TRI.getMatchingSuperReg(Reg, SubReg, &RISCV::GPRRegClass)) + return Super; + } + } + + llvm::reportFatalInternalError( + "getPhysicalGPR called with unsupported register"); +} + static MCRegister getLargestFPRegisterOrZero(const RISCVSubtarget &STI, const TargetRegisterInfo &TRI, MCRegister Reg) { @@ -1481,7 +1502,12 @@ void RISCVFrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero, for (MCRegister Reg : RegsToZero.set_bits()) { if (TRI.isGeneralPurposeRegister(MF, Reg)) { - FinalRegsToZero.set(Reg.id()); + FinalRegsToZero.set(getPhysicalGPR(TRI, Reg).id()); + } else if (RISCV::GPRPairRegClass.contains(Reg)) { + FinalRegsToZero.set( + getPhysicalGPR(TRI, TRI.getSubReg(Reg, RISCV::sub_gpr_even)).id()); + FinalRegsToZero.set( + getPhysicalGPR(TRI, TRI.getSubReg(Reg, RISCV::sub_gpr_odd)).id()); } else if (TRI.isFPRegister(Reg)) { if (MCRegister MaybeReg = getLargestFPRegisterOrZero(STI, TRI, Reg)) FinalRegsToZero.set(MaybeReg.id()); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index a3f968b5ab76f..07f002fccfa66 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -570,6 +570,7 @@ def GPRF16C : RISCVRegisterClass<[f16], 16, (add (sequence "X%u_H", 10, 15), (sequence "X%u_H", 8, 9))> { let DecoderMethod = "DecodeSimpleRegisterClass"; } +def GPRF16X0 : RISCVRegisterClass<[f16], 16, (add X0_H)>; def GPRF16NoX0 : RISCVRegisterClass<[f16], 16, (sub GPRF16, X0_H)>; def GPRF32 : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 17), @@ -584,6 +585,7 @@ def GPRF32C : RISCVRegisterClass<[f32], 32, (add (sequence "X%u_W", 10, 15), (sequence "X%u_W", 8, 9))> { let DecoderMethod = "DecodeSimpleRegisterClass"; } +def GPRF32X0 : RISCVRegisterClass<[f32], 32, (add X0_W)>; def GPRF32NoX0 : RISCVRegisterClass<[f32], 32, (sub GPRF32, X0_W)>; //===----------------------------------------------------------------------===// @@ -1024,6 +1026,6 @@ def MR0 : RISCVRegisterClass<[i8, v8i1], 8, (add M0)>; // Register categories. // -def GeneralPurposeRegisters : RegisterCategory<[GPR]>; +def GeneralPurposeRegisters : RegisterCategory<[GPR, GPRF16, GPRF32]>; -def FixedRegisters : RegisterCategory<[GPRX0]>; +def FixedRegisters : RegisterCategory<[GPRX0, GPRF16X0, GPRF32X0]>; diff --git a/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll b/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll index 28e6c792b9dfd..46b0cba76194b 100644 --- a/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll +++ b/llvm/test/CodeGen/RISCV/zero-call-used-regs.ll @@ -281,4 +281,59 @@ entry: ret double %mul } +define double @used_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used" { +; 64-BITS-LABEL: used_zdinx: +; 64-BITS: # %bb.0: # %entry +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: fcvt.d.s a1, a2 +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: li a1, 0 +; 64-BITS-NEXT: li a2, 0 +; 64-BITS-NEXT: ret +; +; 32-BITS-LABEL: used_zdinx: +; 32-BITS: # %bb.0: # %entry +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: fcvt.d.s a2, a4 +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: li a2, 0 +; 32-BITS-NEXT: li a3, 0 +; 32-BITS-NEXT: li a4, 0 +; 32-BITS-NEXT: ret + +entry: + %conv = fpext float %c to double + %mul1 = fmul double %a, %b + %mul2 = fmul double %mul1, %conv + ret double %mul2 +} + +define double @used_arg_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used-arg" { +; 64-BITS-LABEL: used_arg_zdinx: +; 64-BITS: # %bb.0: # %entry +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: fcvt.d.s a1, a2 +; 64-BITS-NEXT: fmul.d a0, a0, a1 +; 64-BITS-NEXT: li a1, 0 +; 64-BITS-NEXT: li a2, 0 +; 64-BITS-NEXT: ret +; +; 32-BITS-LABEL: used_arg_zdinx: +; 32-BITS: # %bb.0: # %entry +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: fcvt.d.s a2, a4 +; 32-BITS-NEXT: fmul.d a0, a0, a2 +; 32-BITS-NEXT: li a2, 0 +; 32-BITS-NEXT: li a3, 0 +; 32-BITS-NEXT: li a4, 0 +; 32-BITS-NEXT: ret + +entry: + %conv = fpext float %c to double + %mul1 = fmul double %a, %b + %mul2 = fmul double %mul1, %conv + ret double %mul2 +} + attributes #0 = { "target-cpu"="generic" "target-features"="+m,+f,+d" } +attributes #1 = { "target-cpu"="generic" "target-features"="+m,+zdinx" } From 68c0f578f9a2118cb6069c10cc96649d5e27e9b6 Mon Sep 17 00:00:00 2001 From: "forking-google-bazel-bot[bot]" <265904573+forking-google-bazel-bot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:21:05 -0700 Subject: [PATCH 023/125] [Bazel] Fixes 0f9f5a2 (#208562) This fixes 0f9f5a2aba97070971f2d58f2e307f621edf9ada. Buildkite error link: https://buildkite.com/llvm-project/upstream-bazel/builds?commit=0f9f5a2aba97070971f2d58f2e307f621edf9ada Co-authored-by: Google Bazel Bot --- utils/bazel/llvm-project-overlay/clang/BUILD.bazel | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel index ab678a7895711..062fdea0d73d1 100644 --- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel @@ -430,6 +430,16 @@ gentbl_cc_library( ], ) +gentbl_cc_library( + name = "basic_builtins_zos_gen", + tbl_outs = {"include/clang/Basic/BuiltinsZOS.inc": ["-gen-clang-builtins"]}, + tblgen = ":clang-tblgen", + td_file = "include/clang/Basic/BuiltinsZOS.td", + deps = [ + ":BuiltinsBaseTdFiles", + ], +) + gentbl_cc_library( name = "basic_builtins_x86_64_gen", tbl_outs = {"include/clang/Basic/BuiltinsX86_64.inc": ["-gen-clang-builtins"]}, @@ -760,6 +770,7 @@ cc_library( ":basic_builtins_systemz_gen", ":basic_builtins_x86_64_gen", ":basic_builtins_x86_gen", + ":basic_builtins_zos_gen", ":basic_riscv_andes_vector_builtins_gen", ":basic_riscv_sifive_vector_builtins_gen", ":basic_riscv_vector_builtin_cg_gen", From 351b9682b43376a9beb149e45807366029ced1b1 Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Thu, 9 Jul 2026 23:24:05 +0200 Subject: [PATCH 024/125] [AMDGPU] Fix crash on strict fptrunc to bf16 (#208037) --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 11 +- llvm/lib/Target/AMDGPU/VOP3Instructions.td | 2 +- .../CodeGen/AMDGPU/strict_fptrunc_bf16.ll | 151 ++++++++++++++++++ 3 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index bd087fae75403..5c3041d91b390 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -1023,7 +1023,8 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, setOperationAction(ISD::MUL, MVT::i1, Promote); if (Subtarget->hasBF16ConversionInsts()) { - setOperationAction(ISD::FP_ROUND, {MVT::bf16, MVT::v2bf16}, Custom); + setOperationAction({ISD::FP_ROUND, ISD::STRICT_FP_ROUND}, + {MVT::bf16, MVT::v2bf16}, Custom); setOperationAction(ISD::BUILD_VECTOR, MVT::v2bf16, Legal); } @@ -8644,7 +8645,8 @@ SDValue SITargetLowering::splitFP_ROUNDVectorOp(SDValue Op, } SDValue SITargetLowering::lowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const { - SDValue Src = Op.getOperand(0); + bool IsStrict = Op->isStrictFPOpcode(); + SDValue Src = Op.getOperand(IsStrict ? 1 : 0); EVT SrcVT = Src.getValueType(); EVT DstVT = Op.getValueType(); @@ -8687,6 +8689,11 @@ SDValue SITargetLowering::lowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const { // hardware f32 -> bf16 instruction. EVT F32VT = SrcVT.changeElementType(*DAG.getContext(), MVT::f32); SDValue Rod = expandRoundInexactToOdd(F32VT, Src, DL, DAG); + if (IsStrict) { + return DAG.getNode( + ISD::STRICT_FP_ROUND, DL, {DstVT, MVT::Other}, + {Op.getOperand(0), Rod, DAG.getTargetConstant(0, DL, MVT::i32)}); + } return DAG.getNode(ISD::FP_ROUND, DL, DstVT, Rod, DAG.getTargetConstant(0, DL, MVT::i32)); } diff --git a/llvm/lib/Target/AMDGPU/VOP3Instructions.td b/llvm/lib/Target/AMDGPU/VOP3Instructions.td index f2a2f2b3a2499..ebbe89981e4ef 100644 --- a/llvm/lib/Target/AMDGPU/VOP3Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3Instructions.td @@ -1794,7 +1794,7 @@ class VOP3_CVT_SR_FP16_TiedInput_Profile : VOP3_CVT_SCALE_F1632_FP // FIXME: GlobalISel cannot distinguish f16 and bf16 and may start using bf16 patterns // instead of less complex f16. Disable GlobalISel for these for now. -def bf16_fpround : PatFrag <(ops node:$src0), (fpround $src0), [{ return true; }]> { +def bf16_fpround : PatFrag <(ops node:$src0), (any_fpround $src0), [{ return true; }]> { let GISelPredicateCode = [{return false;}]; } diff --git a/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll b/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll new file mode 100644 index 0000000000000..1aa8815e63868 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/strict_fptrunc_bf16.ll @@ -0,0 +1,151 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -mtriple=amdgcn -mcpu=gfx950 < %s | FileCheck --check-prefixes=GFX950 %s +; RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -mattr=-real-true16 < %s | FileCheck --check-prefixes=GFX1250 %s + +define amdgpu_ps void @strict_fptrunc_f32_to_bf16(float %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_f32_to_bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_mov_b32_e32 v3, v2 +; GFX950-NEXT: v_mov_b32_e32 v2, v1 +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX950-NEXT: flat_store_short v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_f32_to_bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_dual_mov_b32 v3, v2 :: v_dual_mov_b32 v2, v1 +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX1250-NEXT: flat_store_b16 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store bfloat %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_f64_to_bf16(double %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_f64_to_bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_f32_f64_e32 v6, v[0:1] +; GFX950-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GFX950-NEXT: v_and_b32_e32 v7, 1, v6 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[4:5]| +; GFX950-NEXT: v_cmp_nlg_f64_e32 vcc, v[0:1], v[4:5] +; GFX950-NEXT: v_cmp_eq_u32_e64 s[0:1], 1, v7 +; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v0, v6, v0 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX950-NEXT: flat_store_short v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_f64_to_bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_f32_f64_e32 v6, v[0:1] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[4:5], v6 +; GFX1250-NEXT: v_cmp_gt_f64_e64 s0, |v[0:1]|, |v[4:5]| +; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[0:1], v[4:5] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s0 +; GFX1250-NEXT: v_dual_add_nc_u32 v0, v6, v0 :: v_dual_bitop2_b32 v7, 1, v6 bitop3:0x40 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(SKIP_2) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_cmp_eq_u32_e64 s0, 1, v7 +; GFX1250-NEXT: s_or_b32 vcc_lo, vcc_lo, s0 +; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v6, vcc_lo +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, s0 +; GFX1250-NEXT: flat_store_b16 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store bfloat %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_v2f32_to_v2bf16(<2 x float> %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_v2f32_to_v2bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX950-NEXT: flat_store_dword v[2:3], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_v2f32_to_v2bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX1250-NEXT: flat_store_b32 v[2:3], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store <2 x bfloat> %cvt, ptr %out + ret void +} + +define amdgpu_ps void @strict_fptrunc_v2f64_to_v2bf16(<2 x double> %a, ptr %out) #0 { +; GFX950-LABEL: strict_fptrunc_v2f64_to_v2bf16: +; GFX950: ; %bb.0: +; GFX950-NEXT: v_cvt_f32_f64_e32 v8, v[2:3] +; GFX950-NEXT: v_and_b32_e32 v6, 1, v8 +; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v6 +; GFX950-NEXT: v_cvt_f64_f32_e32 v[6:7], v8 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[2:3]|, |v[6:7]| +; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[2:3], v[6:7] +; GFX950-NEXT: v_cvt_f32_f64_e32 v9, v[0:1] +; GFX950-NEXT: v_cndmask_b32_e64 v2, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v2, v8, v2 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v6, v2, v8, vcc +; GFX950-NEXT: v_cvt_f64_f32_e32 v[2:3], v9 +; GFX950-NEXT: v_and_b32_e32 v10, 1, v9 +; GFX950-NEXT: v_cmp_gt_f64_e64 s[2:3], |v[0:1]|, |v[2:3]| +; GFX950-NEXT: v_cmp_ne_u32_e32 vcc, 0, v10 +; GFX950-NEXT: v_cmp_nlg_f64_e64 s[0:1], v[0:1], v[2:3] +; GFX950-NEXT: v_cndmask_b32_e64 v0, -1, 1, s[2:3] +; GFX950-NEXT: v_add_u32_e32 v0, v9, v0 +; GFX950-NEXT: s_or_b64 vcc, vcc, s[0:1] +; GFX950-NEXT: v_cndmask_b32_e32 v0, v0, v9, vcc +; GFX950-NEXT: v_cvt_pk_bf16_f32 v0, v0, v6 +; GFX950-NEXT: flat_store_dword v[4:5], v0 +; GFX950-NEXT: s_endpgm +; +; GFX1250-LABEL: strict_fptrunc_v2f64_to_v2bf16: +; GFX1250: ; %bb.0: +; GFX1250-NEXT: s_setreg_imm32_b32 hwreg(HW_REG_WAVE_MODE, 25, 1), 1 ; msbs: dst=0 src0=0 src1=0 src2=0 +; GFX1250-NEXT: v_cvt_f32_f64_e32 v10, v[2:3] +; GFX1250-NEXT: v_cvt_f32_f64_e32 v11, v[0:1] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(NEXT) | instid1(VALU_DEP_2) +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[6:7], v10 +; GFX1250-NEXT: v_cvt_f64_f32_e32 v[8:9], v11 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_2) | instskip(SKIP_1) | instid1(VALU_DEP_3) +; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[2:3]|, |v[6:7]| +; GFX1250-NEXT: v_cmp_nlg_f64_e32 vcc_lo, v[2:3], v[6:7] +; GFX1250-NEXT: v_cmp_nlg_f64_e64 s0, v[0:1], v[8:9] +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_3) | instskip(SKIP_1) | instid1(VALU_DEP_2) +; GFX1250-NEXT: v_cndmask_b32_e64 v2, -1, 1, s1 +; GFX1250-NEXT: v_cmp_gt_f64_e64 s1, |v[0:1]|, |v[8:9]| +; GFX1250-NEXT: v_dual_add_nc_u32 v1, v10, v2 :: v_dual_bitop2_b32 v13, 1, v11 bitop3:0x40 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_3) +; GFX1250-NEXT: v_cmp_ne_u32_e64 s2, 0, v13 +; GFX1250-NEXT: v_cndmask_b32_e64 v0, -1, 1, s1 +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) | instskip(NEXT) | instid1(VALU_DEP_1) +; GFX1250-NEXT: v_dual_add_nc_u32 v0, v11, v0 :: v_dual_bitop2_b32 v12, 1, v10 bitop3:0x40 +; GFX1250-NEXT: v_cmp_ne_u32_e64 s1, 0, v12 +; GFX1250-NEXT: s_or_b32 vcc_lo, s1, vcc_lo +; GFX1250-NEXT: v_cndmask_b32_e32 v1, v1, v10, vcc_lo +; GFX1250-NEXT: s_or_b32 vcc_lo, s2, s0 +; GFX1250-NEXT: v_cndmask_b32_e32 v0, v0, v11, vcc_lo +; GFX1250-NEXT: s_delay_alu instid0(VALU_DEP_1) +; GFX1250-NEXT: v_cvt_pk_bf16_f32 v0, v0, v1 +; GFX1250-NEXT: flat_store_b32 v[4:5], v0 +; GFX1250-NEXT: s_endpgm + %cvt = call <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double> %a, metadata !"round.tonearest", metadata !"fpexcept.strict") + store <2 x bfloat> %cvt, ptr %out + ret void +} + +declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f32(float, metadata, metadata) +declare bfloat @llvm.experimental.constrained.fptrunc.bf16.f64(double, metadata, metadata) +declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f32(<2 x float>, metadata, metadata) +declare <2 x bfloat> @llvm.experimental.constrained.fptrunc.v2bf16.v2f64(<2 x double>, metadata, metadata) + +attributes #0 = { strictfp } From 5363d61acd674b85b22668a7b5545ff638af7ef3 Mon Sep 17 00:00:00 2001 From: Kazu Hirata Date: Thu, 9 Jul 2026 14:26:22 -0700 Subject: [PATCH 025/125] [SampleProfile] Introduce stabilizeTable (NFC) (#208501) This patch adds stabilizeTable to replace duplicate code involving O(N) heap allocations and hash lookups. The new helper function returns pointers to key-value pairs sorted by key. Since the keys in MapVector are already guaranteed to be unique, using std::set for sorting allocates unnecessary tree nodes on the heap. Assisted-by: Antigravity --- .../llvm/ProfileData/SampleProfWriter.h | 3 -- llvm/lib/ProfileData/SampleProfWriter.cpp | 54 ++++++++----------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h index b7a9382f08bb7..8756c038ff17c 100644 --- a/llvm/include/llvm/ProfileData/SampleProfWriter.h +++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h @@ -22,7 +22,6 @@ #include "llvm/Support/raw_ostream.h" #include #include -#include #include namespace llvm { @@ -224,8 +223,6 @@ class LLVM_ABI SampleProfileWriterBinary : public SampleProfileWriter { virtual std::error_code writeContextIdx(const SampleContext &Context); std::error_code writeNameIdx(FunctionId FName); std::error_code writeBody(const FunctionSamples &S); - inline void stablizeNameTable(MapVector &NameTable, - std::set &V); MapVector NameTable; diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index dd051e265284d..62bdf5343a2f0 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -347,21 +346,34 @@ std::error_code SampleProfileWriterExtBinaryBase::writeFuncMetadata( return sampleprof_error::success; } +template +static SmallVector *, 0> +stabilizeTable(MapVector &Table) { + SmallVector *, 0> Entries( + llvm::make_pointer_range(Table)); + + llvm::sort(Entries, + [](const auto *L, const auto *R) { return L->first < R->first; }); + + for (const auto &[I, Entry] : llvm::enumerate(Entries)) + Entry->second = I; + + return Entries; +} + std::error_code SampleProfileWriterExtBinaryBase::writeNameTable() { if (!UseMD5) return SampleProfileWriterBinary::writeNameTable(); auto &OS = *OutputStream; - std::set V; - stablizeNameTable(NameTable, V); // Write out the MD5 name table. We wrote unencoded MD5 so reader can // retrieve the name using the name index without having to read the // whole name table. encodeULEB128(NameTable.size(), OS); support::endian::Writer Writer(OS, llvm::endianness::little); - for (auto N : V) - Writer.write(N.getHashCode()); + for (const auto *Entry : stabilizeTable(NameTable)) + Writer.write(Entry->first.getHashCode()); return sampleprof_error::success; } @@ -391,21 +403,11 @@ std::error_code SampleProfileWriterExtBinaryBase::writeNameTableSection( } std::error_code SampleProfileWriterExtBinaryBase::writeCSNameTableSection() { - // Sort the names to make CSNameTable deterministic. - std::set OrderedContexts; - for (const auto &I : CSNameTable) - OrderedContexts.insert(I.first); - assert(OrderedContexts.size() == CSNameTable.size() && - "Unmatched ordered and unordered contexts"); - uint64_t I = 0; - for (auto &Context : OrderedContexts) - CSNameTable[Context] = I++; - auto &OS = *OutputStream; - encodeULEB128(OrderedContexts.size(), OS); + encodeULEB128(CSNameTable.size(), OS); support::endian::Writer Writer(OS, llvm::endianness::little); - for (auto Context : OrderedContexts) { - auto Frames = Context.getContextFrames(); + for (const auto *Entry : stabilizeTable(CSNameTable)) { + auto Frames = Entry->first.getContextFrames(); encodeULEB128(Frames.size(), OS); for (auto &Callsite : Frames) { if (std::error_code EC = writeNameIdx(Callsite.Func)) @@ -731,25 +733,13 @@ void SampleProfileWriterExtBinaryBase::addContext( } } -void SampleProfileWriterBinary::stablizeNameTable( - MapVector &NameTable, std::set &V) { - // Sort the names to make NameTable deterministic. - for (const auto &I : NameTable) - V.insert(I.first); - int i = 0; - for (const FunctionId &N : V) - NameTable[N] = i++; -} - std::error_code SampleProfileWriterBinary::writeNameTable() { auto &OS = *OutputStream; - std::set V; - stablizeNameTable(NameTable, V); // Write out the name table. encodeULEB128(NameTable.size(), OS); - for (auto N : V) { - OS << N; + for (const auto *Entry : stabilizeTable(NameTable)) { + OS << Entry->first; encodeULEB128(0, OS); } return sampleprof_error::success; From 45f9445107e6acabc93fc47d4222ecfcdb50620d Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Thu, 9 Jul 2026 14:33:47 -0700 Subject: [PATCH 026/125] Fix typo (#208560) --- lldb/bindings/interface/SBValueDocstrings.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/bindings/interface/SBValueDocstrings.i b/lldb/bindings/interface/SBValueDocstrings.i index bedb553e94c3a..e24c3df5c0bf4 100644 --- a/lldb/bindings/interface/SBValueDocstrings.i +++ b/lldb/bindings/interface/SBValueDocstrings.i @@ -213,7 +213,7 @@ linked list." or SetData(). Returns False when the value is not writable. An example would be a - variable values reconstructed from debug info via a computation or a constant. + variable value reconstructed from debug info via a computation or a constant. A True result does not guarantee a write will succeed; other runtime conditions may still prevent a successful write." ) lldb::SBValue::CanSetValue; From 4ccb701ff80976cd59cfe55198df533f9913f66a Mon Sep 17 00:00:00 2001 From: Victor Perez Date: Thu, 9 Jul 2026 17:34:56 -0400 Subject: [PATCH 027/125] [mlir][RemoveDeadValues] Use `SymbolUserMap` to avoid quadratic symbol lookups (#205448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `processFuncOp` previously called `funcOp.getSymbolUses(module)` for every function, which walks the entire module to find that function's callers. Since `processFuncOp` runs once per function, the pass was effectively *O(numFunctions * numOperations)*. Build a `SymbolUserMap` once up front in `runOnOperation()` and look up each function's callers in *O(1)*, making the collection phase linear in the size of the module. This is behavior-preserving: the map is read only during the mutation-free collection walk, and all IR erasure happens afterwards in `cleanUpDeadVals`, so the map cannot become stale while it is in use. --- **Note:** AI used to generate part of the code in this PR. Signed-off-by: Victor Perez Carrasco Co-authored-by: Víctor Pérez Carrasco Co-authored-by: mlevesquedion --- mlir/lib/Transforms/RemoveDeadValues.cpp | 29 +++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp index f0a210a2ededb..812ae50d89ed1 100644 --- a/mlir/lib/Transforms/RemoveDeadValues.cpp +++ b/mlir/lib/Transforms/RemoveDeadValues.cpp @@ -259,7 +259,7 @@ static void processSimpleOp(Operation *op, RunLivenessAnalysis &la, } /// Process a function-like operation `funcOp` using the liveness analysis `la` -/// and the IR in `module`. If it is not public or external: +/// and `symbolUserMap`. If it is not public or external: /// (1) Adding its non-live arguments to a list for future removal. /// (2) Marking their corresponding operands in its callers for removal. /// (3) Identifying and enqueueing unnecessary terminator operands @@ -268,7 +268,8 @@ static void processSimpleOp(Operation *op, RunLivenessAnalysis &la, /// (5) Collecting the uses of these return values in its callers for future /// removal. /// (6) Marking all its results as non-live values. -static void processFuncOp(FunctionOpInterface funcOp, Operation *module, +static void processFuncOp(FunctionOpInterface funcOp, + const SymbolUserMap &symbolUserMap, RunLivenessAnalysis &la, DenseSet &nonLiveSet, RDVFinalCleanupList &cl) { LDBG() << "Processing function op: " @@ -279,10 +280,8 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, << funcOp.getOperation()->getName(); return; } - SymbolTable::UseRange uses = *funcOp.getSymbolUses(module); - if (llvm::any_of(uses, [](SymbolTable::SymbolUse use) { - return !isa(use.getUser()); - })) { + ArrayRef users = symbolUserMap.getUsers(funcOp); + if (!llvm::all_of(users, llvm::IsaPred)) { // If a non-call operation references the function (e.g. spirv.EntryPoint), // we cannot safely remove arguments or return values since we don't know // what the user expects. Skip this function entirely. @@ -301,8 +300,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // Do (2). (Skip creating generic operand cleanup entries for call ops. // Call arguments will be removed in the call-site specific segment-aware // cleanup, avoiding generic eraseOperands bitvector mechanics.) - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { // Push an empty operand cleanup entry so that call-site specific logic in // cleanUpDeadVals runs (it keys off CallOpInterface). The BitVector is // intentionally all false to avoid generic erasure. @@ -336,8 +334,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // since it forwards only to non-live value(s) (%1#1). size_t numReturns = funcOp.getNumResults(); BitVector nonLiveRets(numReturns, true); - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { assert(isa(callOp) && "expected a call-like user"); BitVector liveCallRets = markLives(callOp->getResults(), nonLiveSet, la); nonLiveRets &= liveCallRets.flip(); @@ -360,8 +357,7 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module, // Do (5) and (6). if (numReturns == 0) return; - for (SymbolTable::SymbolUse use : uses) { - Operation *callOp = use.getUser(); + for (Operation *callOp : users) { assert(isa(callOp) && "expected a call-like user"); cl.results.push_back({callOp, nonLiveRets}); collectNonLiveValues(nonLiveSet, callOp->getResults(), nonLiveRets); @@ -770,6 +766,13 @@ void RemoveDeadValues::runOnOperation() { auto &la = getAnalysis(); Operation *module = getOperation(); + // Build a symbol user map once up front so that processFuncOp can look up the + // callers of each function in O(1). Otherwise, each call would walk the + // entire module to find the callers, making the pass O(numFunctions * + // numOperations). + SymbolTableCollection symbolTableCollection; + SymbolUserMap symbolUserMap(symbolTableCollection, module); + // Tracks values eligible for erasure - complements liveness analysis to // identify "droppable" values. DenseSet deadVals; @@ -780,7 +783,7 @@ void RemoveDeadValues::runOnOperation() { module->walk([&](Operation *op) { if (auto funcOp = dyn_cast(op)) { - processFuncOp(funcOp, module, la, deadVals, finalCleanupList); + processFuncOp(funcOp, symbolUserMap, la, deadVals, finalCleanupList); } else if (auto regionBranchOp = dyn_cast(op)) { processRegionBranchOp(regionBranchOp, la, deadVals, finalCleanupList); } else if (auto branchOp = dyn_cast(op)) { From ed907dee954660295f0b7de0587cfbedc708aa7e Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Thu, 9 Jul 2026 14:43:58 -0700 Subject: [PATCH 028/125] [alpha.webkit.UncheckedLambdaCapturesChecker] Split unchecked lambda capture checker (#201044) Split alpha.webkit.UncheckedLambdaCapturesChecker off of UncountedLambdaCapturesChecker, which currently checks for the use of ref counted objects as well as CheckedPtr capable types unlike all other WebKit checkers, which only check for one type of smart pointers. Also improve the wording of the warning text so that it can be easily extended to support checking for the lambda capturing of raw pointers and references to CheckedPtr/CheckedRef. --- clang/docs/analyzer/checkers.rst | 17 + .../clang/StaticAnalyzer/Checkers/Checkers.td | 4 + .../WebKit/RawPtrRefLambdaCapturesChecker.cpp | 132 ++++- .../WebKit/call-args-wtf-containers.cpp | 19 - .../Analysis/Checkers/WebKit/mock-types.h | 208 ++++++- .../WebKit/unchecked-lambda-captures.cpp | 533 ++++++++++++++++++ ...mbda-captures-decl-protects-this-crash.cpp | 4 +- .../WebKit/uncounted-lambda-captures.cpp | 241 +------- .../WebKit/unretained-lambda-captures-arc.mm | 14 +- .../WebKit/unretained-lambda-captures.mm | 154 +---- 10 files changed, 908 insertions(+), 418 deletions(-) create mode 100644 clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index 062c8b0469223..92766d843d4b1 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3967,6 +3967,23 @@ The goal of this rule is to make sure that lifetime of any dynamically allocated The rules of when to use and not to use CheckedPtr / CheckedRef are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects. +alpha.webkit.UncheckedLambdaCapturesChecker +""""""""""""""""""""""""""""""""""""""""""" +Raw pointers and references to unchecked types can't be captured in lambdas. Only CheckedPtr or CheckedRef is allowed. + +.. code-block:: cpp + + struct CheckedObject { + void incrementCheckedPtr() {} + void decrementCheckedPtr() {} + }; + + void foo(CheckedObject* a, CheckedObject& b) { + [&, a](){ // warn about 'a' + do_something(b); // warn about 'b' + }; + }; + alpha.webkit.UnretainedCallArgsChecker """""""""""""""""""""""""""""""""""""" The goal of this rule is to make sure that lifetime of any dynamically allocated NS or CF objects passed as a call argument keeps its memory region past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. NS or CF objects aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to unretained types. diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index d33b21245bd7f..949e20d1fb98d 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1773,6 +1773,10 @@ def UncountedLocalVarsChecker : Checker<"UncountedLocalVarsChecker">, HelpText<"Check uncounted local variables.">, Documentation; +def UncheckedLambdaCapturesChecker : Checker<"UncheckedLambdaCapturesChecker">, + HelpText<"Check unchecked lambda captures.">, + Documentation; + def UncheckedLocalVarsChecker : Checker<"UncheckedLocalVarsChecker">, HelpText<"Check unchecked local variables.">, Documentation; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 287c7dd039dd8..013608c0ff32c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -1,4 +1,4 @@ -//=======- UncountedLambdaCapturesChecker.cpp --------------------*- C++ -*-==// +//=======- RawPtrRefLambdaCapturesChecker.cpp --------------------*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,7 +36,7 @@ class RawPtrRefLambdaCapturesChecker virtual std::optional isUnsafePtr(QualType) const = 0; virtual bool isPtrType(const std::string &) const = 0; - virtual const char *ptrKind(QualType QT) const = 0; + virtual const char *typeName() const = 0; void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, BugReporter &BRArg) const { @@ -542,25 +542,40 @@ class RawPtrRefLambdaCapturesChecker SmallString<100> Buf; llvm::raw_svector_ostream Os(Buf); - if (Capture.isExplicit()) { + if (Capture.isExplicit()) Os << "Captured "; - } else { + else Os << "Implicitly captured "; - } - if (isa(T) || isa(T)) { - Os << "raw-pointer "; - } else { - Os << "reference "; - } - + Os << "variable "; printQuotedQualifiedName(Os, CapturedVar); - Os << " to " << ptrKind(T) << " type is unsafe."; + + bool IsUnsafePtr = CapturedVar->getType() == T; + if (IsUnsafePtr) + Os << " is a "; + else + Os << " contains a "; + auto *CapturedType = T.getTypePtrOrNull(); + printPointer(Os, CapturedType); PathDiagnosticLocation BSLoc(Location, BR->getSourceManager()); auto Report = std::make_unique(Bug, Os.str(), BSLoc); BR->emitReport(std::move(Report)); } + ObjCInterfaceDecl *getObjCDecl(const Type *TypePtr) const { + auto *PointeeType = TypePtr->getPointeeType().getTypePtrOrNull(); + if (!PointeeType) + return nullptr; + auto *Desugared = PointeeType->getUnqualifiedDesugaredType(); + if (!Desugared) + return nullptr; + if (auto *ObjCType = dyn_cast(Desugared)) + return ObjCType->getDecl(); + if (auto *ObjCType = dyn_cast(Desugared)) + return ObjCType->getInterface(); + return nullptr; + } + void reportBugOnThisPtr(const LambdaCapture &Capture, const QualType T) const { SmallString<100> Buf; @@ -572,41 +587,66 @@ class RawPtrRefLambdaCapturesChecker Os << "Implicitly captured "; } - Os << "raw-pointer 'this' to " << ptrKind(T) << " type is unsafe."; + Os << "variable 'this' is a raw pointer to " << typeName(); + if (auto *RD = T->getPointeeCXXRecordDecl()) { + Os << " "; + printQuotedQualifiedName(Os, RD); + } PathDiagnosticLocation BSLoc(Capture.getLocation(), BR->getSourceManager()); auto Report = std::make_unique(Bug, Os.str(), BSLoc); BR->emitReport(std::move(Report)); } + + virtual void printPointer(llvm::raw_svector_ostream &Os, + const Type *T) const { + T = T->getUnqualifiedDesugaredType(); + bool IsPtr = isa(T) || isa(T); + Os << (IsPtr ? "raw pointer" : "raw reference") << " to "; + Os << typeName(); + + if (auto *RD = T->getPointeeType()->getAsRecordDecl()) { + Os << " "; + printQuotedQualifiedName(Os, RD); + } else if (auto *ObjCDecl = getObjCDecl(T)) { + Os << " "; + printQuotedQualifiedName(Os, ObjCDecl); + } + } }; class UncountedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { public: UncountedLambdaCapturesChecker() - : RawPtrRefLambdaCapturesChecker("Lambda capture of uncounted or " - "unchecked variable") {} + : RawPtrRefLambdaCapturesChecker("Lambda capture of uncounted variable") { + } std::optional isUnsafePtr(QualType QT) const final { - auto result1 = isUncountedPtr(QT); - auto result2 = isUncheckedPtr(QT); - if (result1 && *result1) - return true; - if (result2 && *result2) - return true; - if (result1) - return *result1; - return result2; + return isUncountedPtr(QT.getCanonicalType()); } virtual bool isPtrType(const std::string &Name) const final { - return isRefType(Name) || isCheckedPtr(Name); + return isRefType(Name); + } + + const char *typeName() const final { return "ref-countable type"; } +}; + +class UncheckedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { +public: + UncheckedLambdaCapturesChecker() + : RawPtrRefLambdaCapturesChecker("Lambda capture of unchecked variable") { } - const char *ptrKind(QualType QT) const final { - if (isUncounted(QT)) - return "uncounted"; - return "unchecked"; + std::optional isUnsafePtr(QualType QT) const final { + return isUncheckedPtr(QT.getCanonicalType()); } + + virtual bool isPtrType(const std::string &Name) const final { + return isCheckedPtr(Name); + } + + const char *typeName() const final { return "CheckedPtr capable type"; } }; class UnretainedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { @@ -627,7 +667,30 @@ class UnretainedLambdaCapturesChecker : public RawPtrRefLambdaCapturesChecker { return isRetainPtrOrOSPtr(Name); } - const char *ptrKind(QualType QT) const final { return "unretained"; } + const char *typeName() const final { return "retainable type"; } + + void printPointer(llvm::raw_svector_ostream &Os, const Type *T) const final { + if (auto *ObjCPtr = dyn_cast(T)) { + for (ObjCProtocolDecl *P : ObjCPtr->quals()) { + if (const auto *II = P->getIdentifier()) { + auto Name = II->getName(); + if (Name.starts_with("OS_")) { + Os << typeName() << " "; + printQuotedQualifiedName(Os, P); + return; + } + } + } + } + if (!isa(T) && T->getAs()) { + auto Typedef = T->getAs(); + assert(Typedef); + Os << typeName() << " "; + printQuotedQualifiedName(Os, Typedef->getDecl()); + return; + } + return RawPtrRefLambdaCapturesChecker::printPointer(Os, T); + } }; } // namespace @@ -641,6 +704,15 @@ bool ento::shouldRegisterUncountedLambdaCapturesChecker( return true; } +void ento::registerUncheckedLambdaCapturesChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} + +bool ento::shouldRegisterUncheckedLambdaCapturesChecker( + const CheckerManager &mgr) { + return true; +} + void ento::registerUnretainedLambdaCapturesChecker(CheckerManager &Mgr) { Mgr.registerChecker(); } diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp index 17e25d9a62703..45e40e051c18e 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-wtf-containers.cpp @@ -104,25 +104,6 @@ namespace WTF { unsigned m_size { 0 }; }; - template - class HashMap { - public: - struct Item { - T key; - S value; - }; - - template Item* find(U&) const; - template bool contains(U&) const; - template S* get(U&) const; - template S* inlineGet(U&) const; - template void add(U&) const; - template void remove(U&) const; - - private: - Item* m_table { nullptr }; - }; - template class WeakHashSet { public: diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index de5c2d35f2408..87b495f526f27 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -11,7 +11,17 @@ template struct remove_reference { typedef T type; }; -template typename remove_reference::type&& move(T&& t); +template T&& move(T& t) { return static_cast(t); } +template T&& move(T&& t) { return t; } + +} + +#endif + +#ifndef mock_types_1103988513531 +#define mock_types_1103988513531 + +namespace std { template T exchange(T& t, U&& u) @@ -29,21 +39,6 @@ T exchange(T& t, decltype(nullptr)) return r; } -} - -#endif - -namespace WTF { - -template typename std::remove_reference::type&& move(T&& t); - -} - -#ifndef mock_types_1103988513531 -#define mock_types_1103988513531 - -namespace std { - template class unique_ptr { private: @@ -68,6 +63,186 @@ class unique_ptr { explicit operator bool() const { return !!t; } }; +namespace ranges { + +template +void for_each(IteratorType first, IteratorType last, CallbackType callback) { + for (auto it = first; !(it == last); ++it) + callback(*it); +} + +struct all_of_impl { + template + constexpr bool operator()(const Collection& collection, Predicate predicate) const { + for (auto it = collection.begin(), end = collection.end(); it != end; ++it) { + if (!predicate(*it)) + return false; + } + return true; + } +}; +inline constexpr auto all_of = all_of_impl {}; + +} + +} + +namespace WTF { + +template typename std::remove_reference::type&& move(T&& t); + +namespace Detail { + +template +class CallableWrapperBase { +public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; +}; + +template class CallableWrapper; + +template +class CallableWrapper : public CallableWrapperBase { +public: + explicit CallableWrapper(CallableType& callable) + : m_callable(callable) { } + Out call(In... in) final { return m_callable(in...); } + +private: + CallableType m_callable; +}; + +} // namespace Detail + +template class Function; + +template Function adopt(Detail::CallableWrapperBase*); + +template +class Function { +public: + using Impl = Detail::CallableWrapperBase; + + Function() = default; + + template + Function(FunctionType f) + : m_callableWrapper(new Detail::CallableWrapper(f)) { } + + Out operator()(In... in) const { return m_callableWrapper->call(in...); } + explicit operator bool() const { return !!m_callableWrapper; } + +private: + enum AdoptTag { Adopt }; + Function(Impl* impl, AdoptTag) + : m_callableWrapper(impl) + { + } + + friend Function adopt(Impl*); + + std::unique_ptr m_callableWrapper; +}; + +template Function adopt(Detail::CallableWrapperBase* impl) +{ + return Function(impl, Function::Adopt); +} + +template +class HashMap { +public: + HashMap(); + HashMap([[clang::noescape]] const Function&); + void ensure(const KeyType&, [[clang::noescape]] const Function&); + bool operator+([[clang::noescape]] const Function&) const; + static void ifAny(HashMap, [[clang::noescape]] const Function&); + + template ValueType* find(U&) const; + template bool contains(U&) const; + template ValueType* get(U&) const; + template ValueType* inlineGet(U&) const; + template void add(U&) const; + template void remove(U&) const; + +private: + ValueType* m_table { nullptr }; +}; + +class ScopeExit final { +public: + template + explicit ScopeExit(ExitFunctionParameter&& exitFunction) + : m_exitFunction(std::move(exitFunction)) { + } + + ScopeExit(ScopeExit&& other) + : m_exitFunction(std::move(other.m_exitFunction)) + , m_execute(std::move(other.m_execute)) { + } + + ~ScopeExit() { + if (m_execute) + m_exitFunction(); + } + + WTF::Function take() { + m_execute = false; + return std::move(m_exitFunction); + } + + void release() { m_execute = false; } + + ScopeExit(const ScopeExit&) = delete; + ScopeExit& operator=(const ScopeExit&) = delete; + ScopeExit& operator=(ScopeExit&&) = delete; + +private: + WTF::Function m_exitFunction; + bool m_execute { true }; +}; + +template ScopeExit makeScopeExit(ExitFunction&&); +template +ScopeExit makeScopeExit(ExitFunction&& exitFunction) +{ + return ScopeExit(std::move(exitFunction)); +} + +// Visitor adapted from http://stackoverflow.com/questions/25338795/is-there-a-name-for-this-tuple-creation-idiom + +template struct Visitor : Visitor, Visitor { + Visitor(A a, B... b) + : Visitor(a) + , Visitor(b...) + { + } + + using Visitor::operator (); + using Visitor::operator (); +}; + +template struct Visitor : A { + Visitor(A a) + : A(a) + { + } + + using A::operator(); +}; + +template Visitor makeVisitor(F... f) +{ + return Visitor(f...); +} + +void opaqueFunction(); +template void visit(Visitor&& v, Variants&&... values) +{ + opaqueFunction(); +} + }; template @@ -308,6 +483,7 @@ class CheckedObj { void incrementCheckedPtrCount() { ++m_ptrCount; } void decrementCheckedPtrCount() { --m_ptrCount; } void method(); + void constMethod() const; int trivial() { return 123; } CheckedObj* next(); diff --git a/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp new file mode 100644 index 0000000000000..611c62063db0a --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/unchecked-lambda-captures.cpp @@ -0,0 +1,533 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLambdaCapturesChecker -verify %s + +#include "mock-types.h" + +struct A { + static void b(); +}; + +CheckedObj* make_obj(); + +void someFunction(); +template void call(Callback callback) { + someFunction(); + callback(); +} +void callAsync(const WTF::Function&); + +void raw_ptr() { + CheckedObj* checked_ptr_capable = make_obj(); + auto foo1 = [checked_ptr_capable](){ + // expected-warning@-1{{Captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable->method(); + }; + auto foo2 = [&checked_ptr_capable](){ + // expected-warning@-1{{Captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable->method(); + }; + auto foo3 = [&](){ + checked_ptr_capable->method(); + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + checked_ptr_capable = nullptr; + }; + + auto foo4 = [=](){ + checked_ptr_capable->method(); + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }; + + call(foo1); + call(foo2); + call(foo3); + call(foo4); + + // Confirm that the checker respects [[clang::suppress]]. + CheckedObj* suppressed_checked_ptr_capable = nullptr; + [[clang::suppress]] auto foo5 = [suppressed_checked_ptr_capable](){}; + // no warning. + call(foo5); +} + +void references() { + CheckedObj automatic; + CheckedObj& checked_ptr_capable_ref = automatic; + auto foo1 = [checked_ptr_capable_ref](){ checked_ptr_capable_ref.constMethod(); }; + auto foo2 = [&checked_ptr_capable_ref](){ checked_ptr_capable_ref.method(); }; + // expected-warning@-1{{Captured variable 'checked_ptr_capable_ref' is a raw reference to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + auto foo3 = [&](){ checked_ptr_capable_ref.method(); }; + // expected-warning@-1{{Implicitly captured variable 'checked_ptr_capable_ref' is a raw reference to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + auto foo4 = [=](){ checked_ptr_capable_ref.constMethod(); }; + + call(foo1); + call(foo2); + call(foo3); + call(foo4); +} + +void quiet() { +// This code is not expected to trigger any warnings. + { + CheckedObj automatic; + CheckedObj &checked_ptr_capable_ref = automatic; + } + + auto foo3 = [&]() {}; + auto foo4 = [=]() {}; + + call(foo3); + call(foo4); + + CheckedObj *checked_ptr_capable = nullptr; +} + +template +void map(CheckedObj* start, [[clang::noescape]] Callback&& callback) +{ + while (start) { + callback(*start); + start = start->next(); + } +} + +template +void doubleMap(CheckedObj* start, [[clang::noescape]] Callback1&& callback1, Callback2&& callback2) +{ + while (start) { + callback1(*start); + callback2(*start); + start = start->next(); + } +} + +void noescape_lambda() { + CheckedObj* someObj = make_obj(); + CheckedObj* otherObj = make_obj(); + map(make_obj(), [&](CheckedObj& obj) { + otherObj->method(); + }); + doubleMap(make_obj(), [&](CheckedObj& obj) { + otherObj->method(); + }, [&](CheckedObj& obj) { + otherObj->method(); + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + ([&] { + someObj->method(); + })(); +} + +void lambda_capture_param(CheckedObj* obj) { + auto someLambda = [&]() { + obj->method(); + }; + someLambda(); + someLambda(); +} + +struct CheckedObjWithLambdaCapturingThis { + void incrementCheckedPtrCount() const; + void decrementCheckedPtrCount() const; + void nonTrivial(); + + void method_captures_this_safe() { + auto lambda = [&]() { + nonTrivial(); + }; + lambda(); + } + + void method_captures_this_unsafe() { + auto lambda = [&]() { + nonTrivial(); + // expected-warning@-1{{Implicitly captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }; + call(lambda); + } + + void method_captures_this_unsafe_capture_local_var_explicitly() { + CheckedObj* x = make_obj(); + call([this, protectedThis = CheckedPtr { this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }); + } + + void method_captures_this_with_other_protected_var() { + CheckedObj* x = make_obj(); + call([this, protectedX = CheckedPtr { x }]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + protectedX->method(); + }); + } + + void method_captures_this_unsafe_capture_local_var_explicitly_with_deref() { + CheckedObj* x = make_obj(); + call([this, protectedThis = CheckedRef { *this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }); + } + + void method_captures_this_unsafe_local_var_via_vardecl() { + CheckedObj* x = make_obj(); + auto lambda = [this, protectedThis = CheckedRef { *this }, x]() { + // expected-warning@-1{{Captured variable 'x' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + x->method(); + }; + call(lambda); + } + + void method_captures_this_with_guardian() { + auto lambda = [this, protectedThis = CheckedRef { *this }]() { + nonTrivial(); + }; + call(lambda); + } + + void method_captures_this_with_guardian_refptr() { + auto lambda = [this, protectedThis = CheckedPtr { &*this }]() { + nonTrivial(); + }; + call(lambda); + } + + void forEach(const WTF::Function&); + void method_captures_this_with_lambda_with_no_escape() { + auto run = [&]([[clang::noescape]] const WTF::Function& func) { + forEach(func); + }; + run([&](CheckedObj&) { + nonTrivial(); + }); + } + + static void callLambda([[clang::noescape]] const WTF::Function()>&); + void method_captures_this_in_template_method() { + CheckedObj* obj = make_obj(); + WTF::HashMap> nextMap; + nextMap.ensure(3, [&] { + return obj->next(); + }); + nextMap+[&] { + return obj->next(); + }; + WTF::HashMap>::ifAny(nextMap, [&](auto& item) -> bool { + return item->next() && obj->next(); + }); + callLambda([&]() -> CheckedPtr { + return obj->next(); + }); + WTF::HashMap> anotherMap([&] { + return obj->next(); + }); + } + + void callAsyncNoescape([[clang::noescape]] WTF::Function&&); + void method_temp_lambda(CheckedObj* obj) { + callAsyncNoescape([this, otherObj = CheckedPtr { obj }](auto& obj) { + return otherObj.get() == &obj; + }); + } + + void method_nested_lambda() { + callAsync([this, protectedThis = CheckedRef { *this }] { + callAsync([this, protectedThis = static_cast&&>(protectedThis)] { + nonTrivial(); + }); + }); + } + + void method_nested_lambda2() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this, protectedThis = std::move(*protectedThis)] { + nonTrivial(); + }); + }); + } + + void method_nested_lambda3() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this] { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'CheckedObjWithLambdaCapturingThis' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + nonTrivial(); + }); + }); + } + + void method_nested_lambda4() { + callAsync([this, protectedThis = CheckedPtr { this }] { + callAsync([this, protectedThis = WTF::move(*protectedThis)] { + nonTrivial(); + }); + }); + } +}; + +struct NonCheckedObjWithLambdaCapturingThis { + void nonTrivial(); + + void method_captures_this_safe() { + auto lambda = [&]() { + nonTrivial(); + }; + lambda(); + } + + void method_captures_this_unsafe() { + auto lambda = [&]() { + nonTrivial(); + }; + call(lambda); + } +}; + +void trivial_lambda() { + CheckedObj* checked_ptr_capable = make_obj(); + auto trivial_lambda = [&]() { + return checked_ptr_capable->trivial(); + }; + trivial_lambda(); +} + +bool call_lambda_var_decl() { + CheckedObj* checked_ptr_capable = make_obj(); + auto lambda1 = [&]() -> bool { + return checked_ptr_capable->next(); + }; + auto lambda2 = [=]() -> bool { + return checked_ptr_capable->next(); + }; + return lambda1() && lambda2(); +} + +void lambda_with_args(CheckedObj* obj) { + auto trivial_lambda = [&](int v) { + obj->method(); + }; + trivial_lambda(1); +} + +void callFunctionOpaque(WTF::Function&&); +void callFunction(WTF::Function&& function) { + someFunction(); + function(); +} + +void lambda_converted_to_function(CheckedObj* obj) +{ + callFunction([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + callFunctionOpaque([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +void capture_copy_in_lambda(CheckedObj& checked) { + callFunctionOpaque([checked]() mutable { + checked.method(); + }); + auto* ptr = &checked; + callFunctionOpaque([ptr]() mutable { + // expected-warning@-1{{Captured variable 'ptr' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + ptr->method(); + }); +} + +struct TemplateFunctionCallsLambda { + void ref() const; + void deref() const; + + CheckedObj* obj(); + + template + CheckedPtr method(T* t) { + auto ret = ([&]() -> CheckedPtr { + if constexpr (T::isEncodable) + return t; + return obj() ? t : nullptr; + })(); + return ret; + } +}; + +class Iterator { +public: + Iterator(void* array, unsigned long sizeOfElement, unsigned int index); + Iterator(const Iterator&); + Iterator& operator=(const Iterator&); + bool operator==(const Iterator&); + + Iterator& operator++(); + int& operator*(); + +private: + void* current { nullptr }; + unsigned long sizeOfElement { 0 }; +}; + +void ranges_for_each(CheckedObj* obj) { + int array[] = { 1, 2, 3, 4, 5 }; + std::ranges::for_each(Iterator(array, sizeof(*array), 0), Iterator(array, sizeof(*array), 5), [&](int& item) { + obj->method(); + ++item; + }); +} + +class IntCollection { +public: + int* begin(); + int* end(); + const int* begin() const; + const int* end() const; +}; + +class CheckedPtrCapableObj { +public: + void incrementCheckedPtrCount(); + void decrementCheckedPtrCount(); + + bool allOf(const IntCollection&); + bool isMatch(int); + + void call() const; + void callLambda([[clang::noescape]] const WTF::Function& callback) const; + void doSomeWork() const; +}; + +bool CheckedPtrCapableObj::allOf(const IntCollection& collection) { + return std::ranges::all_of(collection, [&](auto& number) { + return isMatch(number); + }); +} + +void CheckedPtrCapableObj::callLambda([[clang::noescape]] const WTF::Function& callback) const +{ + callback(); +} + +void CheckedPtrCapableObj::call() const +{ + auto lambda = [&] { + doSomeWork(); + }; + callLambda(lambda); +} + +void scope_exit(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + }); + someFunction(); + WTF::ScopeExit scope2([&] { + obj->method(); + }); + someFunction(); +} + +void doWhateverWith(WTF::ScopeExit& obj); + +void scope_exit_with_side_effect(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + doWhateverWith(scope); +} + +void scope_exit_static(CheckedObj* obj) { + static auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +WTF::Function scope_exit_take_lambda(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + return scope.take(); +} + +// FIXME: Ideally, we treat release() as a trivial function. +void scope_exit_release(CheckedObj* obj) { + auto scope = WTF::makeScopeExit([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + scope.release(); +} + +void make_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + }); +} + +void use_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + }); + WTF::visit(visitor, obj); +} + +template +void bad_visit(Visitor&, ObjectType*) { + someFunction(); +} + +void static_visitor(CheckedObj* obj) { + static auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); +} + +void make_visitor_with_multiple_lambdas(CheckedObj* obj) { + auto* otherObj = make_obj(); + auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }, [&] { + otherObj->method(); + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + bad_visit(visitor, obj); +} + +void bad_use_visitor(CheckedObj* obj) { + auto visitor = WTF::makeVisitor([&] { + obj->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to CheckedPtr capable type 'CheckedObj' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + }); + bad_visit(visitor, obj); +} + +class LambdaInConstructorDestructor { +public: + LambdaInConstructorDestructor() { + call([this]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'LambdaInConstructorDestructor' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + doWork(); + }); + } + + ~LambdaInConstructorDestructor() { + call([this]() { + // expected-warning@-1{{Captured variable 'this' is a raw pointer to CheckedPtr capable type 'LambdaInConstructorDestructor' [alpha.webkit.UncheckedLambdaCapturesChecker]}} + doWork(); + }); + } + + void incrementCheckedPtrCount() const; + void decrementCheckedPtrCount() const; + + void doWork(); +}; diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp index 0c10c69a97eda..1afbd0df93f18 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures-decl-protects-this-crash.cpp @@ -28,9 +28,9 @@ struct Obj { void foo(Foo foo) { bar([this](auto baz) { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'Obj' [webkit.UncountedLambdaCapturesChecker]}} bar([this, foo = *baz, foo2 = !baz](auto&&) { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'Obj' [webkit.UncountedLambdaCapturesChecker]}} someFunction(); }); }); diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index 43834f5414f41..fc8230838c5cb 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -2,186 +2,6 @@ #include "mock-types.h" -namespace std { - -template -T&& move(T& t) { - return static_cast(t); -} - -namespace ranges { - -template -void for_each(IteratorType first, IteratorType last, CallbackType callback) { - for (auto it = first; !(it == last); ++it) - callback(*it); -} - -struct all_of_impl { - template - constexpr bool operator()(const Collection& collection, Predicate predicate) const { - for (auto it = collection.begin(); it != collection.end(); ++it) { - if (!predicate(*it)) - return false; - } - return true; - } -}; -inline constexpr auto all_of = all_of_impl {}; - -} - -} - -namespace WTF { - -namespace Detail { - -template -class CallableWrapperBase { -public: - virtual ~CallableWrapperBase() { } - virtual Out call(In...) = 0; -}; - -template class CallableWrapper; - -template -class CallableWrapper : public CallableWrapperBase { -public: - explicit CallableWrapper(CallableType& callable) - : m_callable(callable) { } - Out call(In... in) final { return m_callable(in...); } - -private: - CallableType m_callable; -}; - -} // namespace Detail - -template class Function; - -template Function adopt(Detail::CallableWrapperBase*); - -template -class Function { -public: - using Impl = Detail::CallableWrapperBase; - - Function() = default; - - template - Function(FunctionType f) - : m_callableWrapper(new Detail::CallableWrapper(f)) { } - - Out operator()(In... in) const { return m_callableWrapper->call(in...); } - explicit operator bool() const { return !!m_callableWrapper; } - -private: - enum AdoptTag { Adopt }; - Function(Impl* impl, AdoptTag) - : m_callableWrapper(impl) - { - } - - friend Function adopt(Impl*); - - std::unique_ptr m_callableWrapper; -}; - -template Function adopt(Detail::CallableWrapperBase* impl) -{ - return Function(impl, Function::Adopt); -} - -template -class HashMap { -public: - HashMap(); - HashMap([[clang::noescape]] const Function&); - void ensure(const KeyType&, [[clang::noescape]] const Function&); - bool operator+([[clang::noescape]] const Function&) const; - static void ifAny(HashMap, [[clang::noescape]] const Function&); - -private: - ValueType* m_table { nullptr }; -}; - -class ScopeExit final { -public: - template - explicit ScopeExit(ExitFunctionParameter&& exitFunction) - : m_exitFunction(std::move(exitFunction)) { - } - - ScopeExit(ScopeExit&& other) - : m_exitFunction(std::move(other.m_exitFunction)) - , m_execute(std::move(other.m_execute)) { - } - - ~ScopeExit() { - if (m_execute) - m_exitFunction(); - } - - WTF::Function take() { - m_execute = false; - return std::move(m_exitFunction); - } - - void release() { m_execute = false; } - - ScopeExit(const ScopeExit&) = delete; - ScopeExit& operator=(const ScopeExit&) = delete; - ScopeExit& operator=(ScopeExit&&) = delete; - -private: - WTF::Function m_exitFunction; - bool m_execute { true }; -}; - -template ScopeExit makeScopeExit(ExitFunction&&); -template -ScopeExit makeScopeExit(ExitFunction&& exitFunction) -{ - return ScopeExit(std::move(exitFunction)); -} - -// Visitor adapted from http://stackoverflow.com/questions/25338795/is-there-a-name-for-this-tuple-creation-idiom - -template struct Visitor : Visitor, Visitor { - Visitor(A a, B... b) - : Visitor(a) - , Visitor(b...) - { - } - - using Visitor::operator (); - using Visitor::operator (); -}; - -template struct Visitor : A { - Visitor(A a) - : A(a) - { - } - - using A::operator(); -}; - -template Visitor makeVisitor(F... f) -{ - return Visitor(f...); -} - -void opaqueFunction(); -template void visit(Visitor&& v, Variants&&... values) -{ - opaqueFunction(); -} - -} // namespace WTF - struct A { static void b(); }; @@ -198,22 +18,22 @@ void callAsync(const WTF::Function&); void raw_ptr() { RefCountable* ref_countable = make_obj(); auto foo1 = [ref_countable](){ - // expected-warning@-1{{Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable->method(); }; auto foo2 = [&ref_countable](){ - // expected-warning@-1{{Captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable->method(); }; auto foo3 = [&](){ ref_countable->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} ref_countable = nullptr; }; auto foo4 = [=](){ ref_countable->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'ref_countable' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }; call(foo1); @@ -233,9 +53,9 @@ void references() { RefCountable& ref_countable_ref = automatic; auto foo1 = [ref_countable_ref](){ ref_countable_ref.constMethod(); }; auto foo2 = [&ref_countable_ref](){ ref_countable_ref.method(); }; - // expected-warning@-1{{Captured reference 'ref_countable_ref' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'ref_countable_ref' is a raw reference to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} auto foo3 = [&](){ ref_countable_ref.method(); }; - // expected-warning@-1{{Implicitly captured reference 'ref_countable_ref' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'ref_countable_ref' is a raw reference to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} auto foo4 = [=](){ ref_countable_ref.constMethod(); }; call(foo1); @@ -289,7 +109,7 @@ void noescape_lambda() { otherObj->method(); }, [&](RefCountable& obj) { otherObj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); ([&] { someObj->method(); @@ -319,7 +139,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe() { auto lambda = [&]() { nonTrivial(); - // expected-warning@-1{{Implicitly captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} }; call(lambda); } @@ -327,7 +147,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_capture_local_var_explicitly() { RefCountable* x = make_obj(); call([this, protectedThis = RefPtr { this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }); @@ -336,7 +156,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_with_other_protected_var() { RefCountable* x = make_obj(); call([this, protectedX = RefPtr { x }]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); protectedX->method(); }); @@ -345,7 +165,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_capture_local_var_explicitly_with_deref() { RefCountable* x = make_obj(); call([this, protectedThis = Ref { *this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }); @@ -354,7 +174,7 @@ struct RefCountableWithLambdaCapturingThis { void method_captures_this_unsafe_local_var_via_vardecl() { RefCountable* x = make_obj(); auto lambda = [this, protectedThis = Ref { *this }, x]() { - // expected-warning@-1{{Captured raw-pointer 'x' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'x' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); x->method(); }; @@ -432,7 +252,7 @@ struct RefCountableWithLambdaCapturingThis { void method_nested_lambda3() { callAsync([this, protectedThis = RefPtr { this }] { callAsync([this] { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'RefCountableWithLambdaCapturingThis' [webkit.UncountedLambdaCapturesChecker]}} nonTrivial(); }); }); @@ -501,22 +321,11 @@ void lambda_converted_to_function(RefCountable* obj) { callFunction([&]() { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); callFunctionOpaque([&]() { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} - }); -} - -void capture_copy_in_lambda(CheckedObj& checked) { - callFunctionOpaque([checked]() mutable { - checked.method(); - }); - auto* ptr = &checked; - callFunctionOpaque([ptr]() mutable { - // expected-warning@-1{{Captured raw-pointer 'ptr' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} - ptr->method(); + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } @@ -616,7 +425,7 @@ void doWhateverWith(WTF::ScopeExit& obj); void scope_exit_with_side_effect(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); doWhateverWith(scope); } @@ -624,14 +433,14 @@ void scope_exit_with_side_effect(RefCountable* obj) { void scope_exit_static(RefCountable* obj) { static auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } WTF::Function scope_exit_take_lambda(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); return scope.take(); } @@ -640,7 +449,7 @@ WTF::Function scope_exit_take_lambda(RefCountable* obj) { void scope_exit_release(RefCountable* obj) { auto scope = WTF::makeScopeExit([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); scope.release(); } @@ -666,7 +475,7 @@ void bad_visit(Visitor&, ObjectType*) { void static_visitor(RefCountable* obj) { static auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); } @@ -674,10 +483,10 @@ void make_visitor_with_multiple_lambdas(RefCountable* obj) { auto* otherObj = make_obj(); auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }, [&] { otherObj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); bad_visit(visitor, obj); } @@ -685,7 +494,7 @@ void make_visitor_with_multiple_lambdas(RefCountable* obj) { void bad_use_visitor(RefCountable* obj) { auto visitor = WTF::makeVisitor([&] { obj->method(); - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to ref-countable type 'RefCountable' [webkit.UncountedLambdaCapturesChecker]}} }); bad_visit(visitor, obj); } @@ -694,14 +503,14 @@ class LambdaInConstructorDestructor { public: LambdaInConstructorDestructor() { call([this]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'LambdaInConstructorDestructor' [webkit.UncountedLambdaCapturesChecker]}} doWork(); }); } ~LambdaInConstructorDestructor() { call([this]() { - // expected-warning@-1{{Captured raw-pointer 'this' to uncounted type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'this' is a raw pointer to ref-countable type 'LambdaInConstructorDestructor' [webkit.UncountedLambdaCapturesChecker]}} doWork(); }); } diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm index 4e024dea7037a..15337cb011267 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures-arc.mm @@ -139,21 +139,21 @@ void raw_ptr() { auto cf = make_cf(); auto bar1 = [cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar2 = [&cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar3 = [&](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} cf = nullptr; }; auto bar4 = [=](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto os = make_os(); @@ -255,7 +255,7 @@ void noescape_lambda() { CFArrayAppendValue(someCF, nullptr); }, [&](CFIndex count) { CFArrayAppendValue(someCF, nullptr); - // expected-warning@-1{{Implicitly captured reference 'someCF' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someCF' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); dispatch_queue_t someOS = make_os(); @@ -277,13 +277,13 @@ void lambda_converted_to_function(SomeObj* obj, CFMutableArrayRef cf, dispatch_q callFunction([&]() { [obj doWork]; CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }); callFunctionOpaque([&]() { [obj doWork]; CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }); } diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm index 76a1da7707a2a..aad6cd245f1bd 100644 --- a/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm +++ b/clang/test/Analysis/Checkers/WebKit/unretained-lambda-captures.mm @@ -1,111 +1,8 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedLambdaCapturesChecker -verify %s +#include "mock-types.h" #include "objc-mock-types.h" -namespace std { - -template -class unique_ptr { -private: - T *t; - -public: - unique_ptr() : t(nullptr) { } - unique_ptr(T *t) : t(t) { } - ~unique_ptr() { - if (t) - delete t; - } - template unique_ptr(unique_ptr&& u) - : t(u.t) - { - u.t = nullptr; - } - T *get() const { return t; } - T *operator->() const { return t; } - T &operator*() const { return *t; } - unique_ptr &operator=(T *) { return *this; } - explicit operator bool() const { return !!t; } -}; - -}; - -namespace WTF { - -namespace Detail { - -template -class CallableWrapperBase { -public: - virtual ~CallableWrapperBase() { } - virtual Out call(In...) = 0; -}; - -template class CallableWrapper; - -template -class CallableWrapper : public CallableWrapperBase { -public: - explicit CallableWrapper(CallableType& callable) - : m_callable(callable) { } - Out call(In... in) final { return m_callable(in...); } - -private: - CallableType m_callable; -}; - -} // namespace Detail - -template class Function; - -template Function adopt(Detail::CallableWrapperBase*); - -template -class Function { -public: - using Impl = Detail::CallableWrapperBase; - - Function() = default; - - template - Function(FunctionType f) - : m_callableWrapper(new Detail::CallableWrapper(f)) { } - - Out operator()(In... in) const { return m_callableWrapper->call(in...); } - explicit operator bool() const { return !!m_callableWrapper; } - -private: - enum AdoptTag { Adopt }; - Function(Impl* impl, AdoptTag) - : m_callableWrapper(impl) - { - } - - friend Function adopt(Impl*); - - std::unique_ptr m_callableWrapper; -}; - -template Function adopt(Detail::CallableWrapperBase* impl) -{ - return Function(impl, Function::Adopt); -} - -template -class HashMap { -public: - HashMap(); - HashMap([[clang::noescape]] const Function&); - void ensure(const KeyType&, [[clang::noescape]] const Function&); - bool operator+([[clang::noescape]] const Function&) const; - static void ifAny(HashMap, [[clang::noescape]] const Function&); - -private: - ValueType* m_table { nullptr }; -}; - -} // namespace WTF - struct A { static void b(); }; @@ -124,61 +21,61 @@ explicit CallableWrapper(CallableType& callable) void raw_ptr() { SomeObj* obj = make_obj(); auto foo1 = [obj](){ - // expected-warning@-1{{Captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} [obj doWork]; }; call(foo1); auto foo2 = [&obj](){ - // expected-warning@-1{{Captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} [obj doWork]; }; auto foo3 = [&](){ [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} obj = nullptr; }; auto foo4 = [=](){ [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto cf = make_cf(); auto bar1 = [cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar2 = [&cf](){ - // expected-warning@-1{{Captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); }; auto bar3 = [&](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} cf = nullptr; }; auto bar4 = [=](){ CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; auto os = make_os(); auto baz1 = [os](){ - // expected-warning@-1{{Captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }; auto baz2 = [&os](){ - // expected-warning@-1{{Captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); }; auto baz3 = [&](){ dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} os = nullptr; }; auto baz4 = [=](){ dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; call(foo1); @@ -219,6 +116,7 @@ void raw_ptr() { }; // no warning. call(baz5); + } void quiet() { @@ -279,7 +177,7 @@ void noescape_lambda() { [otherObj doWork]; }, [&](SomeObj *obj) { [otherObj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'otherObj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'otherObj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); ([&] { [someObj doWork]; @@ -290,7 +188,7 @@ void noescape_lambda() { CFArrayAppendValue(someCF, nullptr); }, [&](CFIndex count) { CFArrayAppendValue(someCF, nullptr); - // expected-warning@-1{{Implicitly captured reference 'someCF' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someCF' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); dispatch_queue_t someOS = make_os(); @@ -298,7 +196,7 @@ void noescape_lambda() { dispatch_queue_get_label(someOS); }, [&](const char* label) { dispatch_queue_get_label(someOS); - // expected-warning@-1{{Implicitly captured reference 'someOS' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'someOS' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); } @@ -312,19 +210,19 @@ void lambda_converted_to_function(SomeObj* obj, CFMutableArrayRef cf, dispatch_q { callFunction([&]() { [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); callFunctionOpaque([&]() { [obj doWork]; - // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'obj' is a raw pointer to retainable type 'SomeObj' [alpha.webkit.UnretainedLambdaCapturesChecker]}} CFArrayAppendValue(cf, nullptr); - // expected-warning@-1{{Implicitly captured reference 'cf' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'cf' is a retainable type 'CFMutableArrayRef' [alpha.webkit.UnretainedLambdaCapturesChecker]}} dispatch_queue_get_label(os); - // expected-warning@-1{{Implicitly captured reference 'os' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'os' is a retainable type 'dispatch_queue_t' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }); } @@ -340,12 +238,12 @@ -(void)run; @implementation ObjWithSelf -(void)doWork { auto doWork = [&] { - // expected-warning@-1{{Implicitly captured raw-pointer 'self' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'self' is a raw pointer to retainable type 'ObjWithSelf' [alpha.webkit.UnretainedLambdaCapturesChecker]}} someFunction(); [delegate doWork]; }; auto doMoreWork = [=] { - // expected-warning@-1{{Implicitly captured raw-pointer 'self' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'self' is a raw pointer to retainable type 'ObjWithSelf' [alpha.webkit.UnretainedLambdaCapturesChecker]}} someFunction(); [delegate doWork]; }; @@ -357,7 +255,7 @@ -(void)doWork { auto doAdditionalWork = [&] { someFunction(); dispatch_queue_get_label(queuePtr); - // expected-warning@-1{{Implicitly captured raw-pointer 'queuePtr' to unretained type is unsafe [alpha.webkit.UnretainedLambdaCapturesChecker]}} + // expected-warning@-1{{Implicitly captured variable 'queuePtr' is a retainable type 'OS_dispatch_queue' [alpha.webkit.UnretainedLambdaCapturesChecker]}} }; callFunctionOpaque(doWork); callFunctionOpaque(doMoreWork); From fdde3c06cf0b62b3c9f553b4234c5ce0eed86451 Mon Sep 17 00:00:00 2001 From: Aiden Grossman Date: Thu, 9 Jul 2026 21:47:49 +0000 Subject: [PATCH 029/125] [Sema] Properly space namespace comments (#208561) // namespace instead of //namespace. This is consistent with the LLVM coding standards. We took focus on this specific case as it was tripping up some of our internal tooling. --- clang/test/SemaTemplate/concepts-out-of-line-def.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 6c41853cf3b4f..60ab6a4939282 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -915,7 +915,7 @@ namespace FuncTemplateInClass { requires C auto TplClass<0>::buggy() -> void {} // expected-error@-1 {{out-of-line definition of 'buggy' does not match any declaration}} - } //namespace t1 + } // namespace t1 namespace t2 { template struct TplClass { // expected-note {{defined here}} template @@ -928,7 +928,7 @@ namespace FuncTemplateInClass { requires C auto TplClass<0>::buggy() -> void {} // expected-error@-1 {{out-of-line definition of 'buggy' does not match any declaration}} - } //namespace t2 + } // namespace t2 } // namespace FuncTemplateInClass namespace GH139476 { From 5b21ec3b69504f2fa3fcd2c91edf1df57130876c Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 9 Jul 2026 14:50:01 -0700 Subject: [PATCH 030/125] [Support] Optimize signal handling file removal code (#173586) clangd/clangd#1787 describes how LLVM's code for removing partially written files when taking a fatal signal is slower than it should be. This code was substantially rewritten by JF Bastien in aa1333a91f8d8a060bcf5 to make it (more) signal-safe. As written in 2018, the logic always allocates a new node for every file we attempt to protect, and those nodes are added to a global singly linked list and never removed. If you open a lot of output files, suddenly output file opening becomes O(n^2), which is what happened during clangd indexing. Removing files on signals in a multi-threaded environment is really complicated! We can use locks to synchronize between threads that are writing to the list, but we cannot use locks to synchronize against re-entrant signals, and we don't have any great tools for masking or delaying things like SIGTERM. This makes it difficult to assert that we have the one and only reference to a node, even after removing it from the linked structure, so we can safely deallocate it. This implementation sidesteps that problem by reusing nodes on the list with a null Filename pointer. The Filename is null if the file no longer needs to be removed. We replace the filename with a different sentinel while removing files using a CAS operation to simulate a lock acquisition. * Case 1: This is the normal case, works as intended, the list should grow in length to the number of concurrently open files that must be removed on exit, which should be O(# threads) * Case 2: In this case, the signal handler will leak the filename string without a GC root for it, which is fine, since we're exiting. I added a benchmark, and this change makes it 16x faster, and the profile shows that the time is no longer mostly spent in this signal handling code. --------- Co-authored-by: JF Bastien --- llvm/benchmarks/CMakeLists.txt | 1 + llvm/benchmarks/writeToOutputInParallel.cpp | 113 ++++++++++++++++++++ llvm/lib/Support/Unix/Signals.inc | 76 ++++++++----- 3 files changed, 165 insertions(+), 25 deletions(-) create mode 100644 llvm/benchmarks/writeToOutputInParallel.cpp diff --git a/llvm/benchmarks/CMakeLists.txt b/llvm/benchmarks/CMakeLists.txt index fbfc9a63e1e8c..ab15943893f5d 100644 --- a/llvm/benchmarks/CMakeLists.txt +++ b/llvm/benchmarks/CMakeLists.txt @@ -18,6 +18,7 @@ add_benchmark(PointerUnionBM PointerUnionBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(ImmutableSetIteratorBM ImmutableSetIteratorBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(RuntimeLibcallsBench RuntimeLibcalls.cpp PARTIAL_SOURCES_INTENDED) +add_benchmark(writeToOutputInParallelBench writeToOutputInParallel.cpp PARTIAL_SOURCES_INTENDED) if(NOT LLVM_TOOL_LLVM_DRIVER_BUILD) # TODO: Check if the tools are in LLVM_DISTRIBUTION_COMPONENTS with diff --git a/llvm/benchmarks/writeToOutputInParallel.cpp b/llvm/benchmarks/writeToOutputInParallel.cpp new file mode 100644 index 0000000000000..c2b29f07a3eee --- /dev/null +++ b/llvm/benchmarks/writeToOutputInParallel.cpp @@ -0,0 +1,113 @@ +//===- writeToOutputInParallel.cpp - Parallel file writing benchmark ------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "benchmark/benchmark.h" +#include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include + +using namespace llvm; + +// Benchmark parallel file writing using writeToOutput. This simulates scenarios +// where multiple threads are writing files concurrently, which is common in +// parallel compilation scenarios. The goal of this benchmark is to ensure that +// LLVM's global signal handling state updates aren't too expensive. +static void BM_WriteToOutputInParallel(benchmark::State &State) { + const int NumThreads = State.range(0); + const int FilesPerThread = State.range(1); + const int BytesPerFile = 40 * 1024; // ~40KB per file + + for (auto _ : State) { + // Create one top-level unique directory + SmallString<128> TopLevelDir; + if (sys::fs::createUniqueDirectory("writeToOutputBM", TopLevelDir)) { + State.SkipWithError("Failed to create temporary directory"); + return; + } + auto Cleanup = + llvm::scope_exit([&]() { sys::fs::remove_directories(TopLevelDir); }); + + // Create subdirectories for each thread within the top-level directory + std::vector> ThreadDirs; + for (int I = 0; I < NumThreads; ++I) { + SmallString<128> ThreadDir(TopLevelDir); + sys::path::append(ThreadDir, "thread_" + std::to_string(I)); + if (sys::fs::create_directory(ThreadDir)) { + State.SkipWithError("Failed to create thread directory"); + return; + } + ThreadDirs.push_back(ThreadDir); + } + + // Launch threads, each writing multiple files + std::vector Threads; + for (int ThreadIdx = 0; ThreadIdx < NumThreads; ++ThreadIdx) { + Threads.emplace_back([&, ThreadIdx]() { + const auto &ThreadDir = ThreadDirs[ThreadIdx]; + for (int FileIdx = 0; FileIdx < FilesPerThread; ++FileIdx) { + SmallString<128> Path(ThreadDir); + sys::path::append(Path, "file_" + std::to_string(FileIdx) + ".bin"); + + Error E = writeToOutput(Path, [=](raw_ostream &Out) -> Error { + // Write 32-bit integers up to BytesPerFile + const int NumInts = BytesPerFile / sizeof(int32_t); + for (int32_t I = 0; I < NumInts; ++I) { + Out.write(reinterpret_cast(&I), sizeof(I)); + } + return Error::success(); + }); + if (E) { + State.SkipWithError("Failed to create outputfile " + + Path.str().str()); + return; + } + } + }); + } + + // Wait for all threads to complete + for (auto &Thread : Threads) { + Thread.join(); + } + + // Cleanup happens automatically via scope_exit + } + + // Report throughput metrics + const int64_t TotalFiles = NumThreads * FilesPerThread; + const int64_t TotalBytes = TotalFiles * BytesPerFile; + + State.SetItemsProcessed(State.iterations() * TotalFiles); + State.SetBytesProcessed(State.iterations() * TotalBytes); + State.counters["threads"] = NumThreads; + State.counters["files_per_thread"] = FilesPerThread; + State.counters["total_files"] = TotalFiles; +} + +// Test various combinations of thread counts and files per thread +// These represent different parallelism scenarios: +// - Low parallelism, many files per thread (serial-like workload) +// - High parallelism, few files per thread (highly parallel workload) +// - Balanced scenarios + +BENCHMARK(BM_WriteToOutputInParallel) + ->Args({1, 1000}) // 1 thread, 1000 files + ->Args({2, 500}) // 2 threads, 500 files each + ->Args({4, 250}) // 4 threads, 250 files each + ->Args({8, 125}) // 8 threads, 125 files each + ->Args({10, 100}) // 10 threads, 100 files each + ->Args({10, 1000}) // 10 threads, 1000 files each (stress test) + ->Unit(benchmark::kMillisecond); + +BENCHMARK_MAIN(); diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index 981d53985e4bc..772fa37b004ac 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -98,6 +98,10 @@ static std::atomic OneShotPipeSignalFunction = nullptr; namespace { +/// Sentinel stored in a node after the signal handler has removed the file; +/// not a valid path, never freed. +static char InvalidPathSentinel[] = "\01\02\03\04"; + /// Signal-safe removal of files. /// Inserting and erasing from the list isn't signal-safe, but removal of files /// themselves is signal-safe. Memory is freed when the head is freed, deletion @@ -107,8 +111,8 @@ class FileToRemoveList { std::atomic Next = nullptr; FileToRemoveList() = default; - // Not signal-safe. - FileToRemoveList(const std::string &str) : Filename(strdup(str.c_str())) {} + // Takes ownership of \p filename. + FileToRemoveList(char *filename) : Filename(filename) {} public: // Not signal-safe. @@ -116,19 +120,35 @@ public: if (FileToRemoveList *N = Next.exchange(nullptr)) delete N; if (char *F = Filename.exchange(nullptr)) - free(F); + if (F != InvalidPathSentinel) + free(F); } // Not signal-safe. static void insert(std::atomic &Head, const std::string &Filename) { - // Insert the new file at the end of the list. - FileToRemoveList *NewHead = new FileToRemoveList(Filename); + // Reuse a node with a null filename (left behind by erase) if one exists. + // There are two cases where Filename can be special: + // - nullptr: a node left behind by a previous file that we had to remove + // - InvalidPathSentinel: a node whose file is actively being removed by a + // signal handler right now, in which case it's OK if this file doesn't + // get removed. + char *NewFilename = strdup(Filename.c_str()); std::atomic *InsertionPoint = &Head; - FileToRemoveList *OldHead = nullptr; - while (!InsertionPoint->compare_exchange_strong(OldHead, NewHead)) { - InsertionPoint = &OldHead->Next; - OldHead = nullptr; + for (FileToRemoveList *Current = Head.load(); Current; + Current = Current->Next.load()) { + char *NullFilename = nullptr; + if (Current->Filename.compare_exchange_strong(NullFilename, NewFilename)) + return; // Reused a slot. + InsertionPoint = &Current->Next; + } + + // Append the new node at the end; on CAS failure, advance to the new tail. + FileToRemoveList *NewNode = new FileToRemoveList(NewFilename); + FileToRemoveList *OldNext = nullptr; + while (!InsertionPoint->compare_exchange_strong(OldNext, NewNode)) { + InsertionPoint = &OldNext->Next; + OldNext = nullptr; } } @@ -145,11 +165,15 @@ public: if (char *OldFilename = Current->Filename.load()) { if (OldFilename != Filename) continue; - // Leave an empty filename. - OldFilename = Current->Filename.exchange(nullptr); - // The filename might have become null between the time we - // compared it and we exchanged it. - if (OldFilename) + // Leave an empty filename. Use CAS to avoid racing with the signal + // handler (which can't take the writer lock); only clear and free + // if we still own the pointer. + char *Expected = OldFilename; + while (!Current->Filename.compare_exchange_strong(Expected, nullptr)) { + if (Expected == nullptr || Expected == InvalidPathSentinel) + break; + } + if (Expected == OldFilename) free(OldFilename); } } @@ -175,21 +199,23 @@ public: // Signal-safe. static void removeAllFiles(std::atomic &Head) { - // If cleanup were to occur while we're removing files we'd have a bad time. - // Make sure we're OK by preventing cleanup from doing anything while we're - // removing files. If cleanup races with us and we win we'll have a leak, - // but we won't crash. + // This signal-safe code cannot acquire the writer lock, and needs to defend + // against racing writes from the `erase` method above. FileToRemoveList *OldHead = Head.exchange(nullptr); for (FileToRemoveList *currentFile = OldHead; currentFile; currentFile = currentFile->Next.load()) { - // If erasing was occuring while we're trying to remove files we'd look - // at free'd data. Take away the path and put it back when done. - if (char *path = currentFile->Filename.exchange(nullptr)) { - removeFile(path); - - // We're done removing the file, erasing can safely proceed. - currentFile->Filename.exchange(path); + // Take exclusive ownership by swapping in the sentinel (signal-safe: no + // allocation or free). Then put the path back so we don't leak. + char *Path = currentFile->Filename.exchange(InvalidPathSentinel); + if (!Path) { + // Restore an empty slot so future insertions can reuse it. + currentFile->Filename.exchange(nullptr); + } else if (Path != InvalidPathSentinel) { + removeFile(Path); + // Add the path back to the list to create a global root referencing the + // heap allocation, which will pacify leak checkers that run at exit. + currentFile->Filename.exchange(Path); } } From aa6db49c751b53c27529d1e2830ef06f8d48329e Mon Sep 17 00:00:00 2001 From: Alex Langford Date: Thu, 9 Jul 2026 14:50:30 -0700 Subject: [PATCH 031/125] [lldb] Tighten interface for TypeCategoryImpl::AnyMatches (#208321) The last 2 parameters are never actually used by any caller so they can be removed. `only_enabled` defaults to `true` but all callers explicitly set this to false. I removed that and rewrote the body to assume it will always be false. --- .../lldb/DataFormatters/TypeCategory.h | 5 +--- lldb/source/Commands/CommandObjectType.cpp | 6 ++--- lldb/source/DataFormatters/TypeCategory.cpp | 23 +------------------ 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/lldb/include/lldb/DataFormatters/TypeCategory.h b/lldb/include/lldb/DataFormatters/TypeCategory.h index 884a27d76e055..9011b43d44489 100644 --- a/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -347,10 +347,7 @@ class TypeCategoryImpl { std::string GetDescription(); bool AnyMatches(const FormattersMatchCandidate &candidate_type, - FormatCategoryItems items = ALL_ITEM_TYPES, - bool only_enabled = true, - const char **matching_category = nullptr, - FormatCategoryItems *matching_type = nullptr); + FormatCategoryItems items = ALL_ITEM_TYPES); void AutoComplete(CompletionRequest &request, FormatCategoryItems items); diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index d86aca0e71854..c1dc949a7b815 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -2259,8 +2259,7 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, // name-based lookup here to try to prevent conflicts. FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags()); - if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter, - false)) { + if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter)) { if (error) *error = Status::FromErrorStringWithFormatv( "cannot add synthetic for type {0} when " @@ -2401,8 +2400,7 @@ class CommandObjectTypeFilterAdd : public CommandObjectParsed { FormattersMatchCandidate candidate_type( type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags()); lldb::SyntheticChildrenSP entry; - if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth, - false)) { + if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth)) { if (error) *error = Status::FromErrorStringWithFormatv( "cannot add filter for type {0} when " diff --git a/lldb/source/DataFormatters/TypeCategory.cpp b/lldb/source/DataFormatters/TypeCategory.cpp index 4d8663ea9c03e..b1cc0d61b4833 100644 --- a/lldb/source/DataFormatters/TypeCategory.cpp +++ b/lldb/source/DataFormatters/TypeCategory.cpp @@ -185,48 +185,27 @@ uint32_t TypeCategoryImpl::GetCount(FormatCategoryItems items) { } bool TypeCategoryImpl::AnyMatches( - const FormattersMatchCandidate &candidate_type, FormatCategoryItems items, - bool only_enabled, const char **matching_category, - FormatCategoryItems *matching_type) { - if (!IsEnabled() && only_enabled) - return false; - + const FormattersMatchCandidate &candidate_type, FormatCategoryItems items) { if (items & eFormatCategoryItemFormat) { if (m_format_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemFormat; return true; } } if (items & eFormatCategoryItemSummary) { if (m_summary_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemSummary; return true; } } if (items & eFormatCategoryItemFilter) { if (m_filter_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemFilter; return true; } } if (items & eFormatCategoryItemSynth) { if (m_synth_cont.AnyMatches(candidate_type)) { - if (matching_category) - *matching_category = m_name.GetCString(); - if (matching_type) - *matching_type = eFormatCategoryItemSynth; return true; } } From 7ef81943c901b4963f163efe571d7bfa7ced43ff Mon Sep 17 00:00:00 2001 From: Hao Ren Date: Thu, 9 Jul 2026 14:58:50 -0700 Subject: [PATCH 032/125] [Reassociate] Compute value ranks iteratively (NFC) (#204952) ReassociatePass::getRank recursively walks operand def-use chains before memoizing ranks. For a very deep acyclic chain whose tail feeds a reassociable operation, this can recurse once per chain element and overflow the native stack. Compute ranks with an explicit post-order worklist instead. The worklist preserves the existing rank calculation and memoization behavior while bounding native stack use. Co-authored-by: Justin Fargnoli --- llvm/lib/Transforms/Scalar/Reassociate.cpp | 74 +++++++++++++++------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index a5105b84c3117..830b220c21d54 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -203,33 +203,59 @@ void ReassociatePass::BuildRankMap(Function &F, } unsigned ReassociatePass::getRank(Value *V) { - Instruction *I = dyn_cast(V); - if (!I) { - if (isa(V)) return ValueRankMap[V]; // Function argument. - return 0; // Otherwise it's a global or constant, rank 0. - } - - if (unsigned Rank = ValueRankMap[I]) - return Rank; // Rank already known? - - // If this is an expression, return the 1+MAX(rank(LHS), rank(RHS)) so that - // we can reassociate expressions for code motion! Since we do not recurse - // for PHI nodes, we cannot have infinite recursion here, because there - // cannot be loops in the value graph that do not go through PHI nodes. - unsigned Rank = 0, MaxRank = RankMap[I->getParent()]; - for (unsigned i = 0, e = I->getNumOperands(); i != e && Rank != MaxRank; ++i) - Rank = std::max(Rank, getRank(I->getOperand(i))); + // Return 1+MAX(rank(LHS), rank(RHS)) for expressions so we can reassociate + // expressions for code motion. Use an explicit worklist rather than native + // recursion so long acyclic use-def chains do not overflow the stack. + struct RankWorkItem { + Value *V; + unsigned OpNo; + unsigned Rank; + }; - // If this is a 'not' or 'neg' instruction, do not count it for rank. This - // assures us that X and ~X will have the same rank. - if (!match(I, m_Not(m_Value())) && !match(I, m_Neg(m_Value())) && - !match(I, m_FNeg(m_Value()))) - ++Rank; + // Each item is one suspended recursive getRank() call. + // Completed ranks are folded back into the parent. + SmallVector Worklist; + Worklist.push_back(RankWorkItem{V, 0, 0}); + + while (true) { + RankWorkItem &Item = Worklist.back(); + Instruction *I = dyn_cast(Item.V); + unsigned Rank = 0; + if (!I) { + // Function argument, global or constant + Rank = isa(Item.V) ? ValueRankMap[Item.V] : 0; + } else if (ValueRankMap[I]) { + // Instruction that is not movable. + Rank = ValueRankMap[I]; + } else if (Item.OpNo == I->getNumOperands() || + Item.Rank == RankMap[I->getParent()]) { + // All operands were visited or the max block rank was reached. + Rank = Item.Rank; + // If this is a 'not' or 'neg' instruction, do not count it for rank. + // This assures us that X and ~X will have the same rank. + if (!match(I, m_Not(m_Value())) && !match(I, m_Neg(m_Value())) && + !match(I, m_FNeg(m_Value()))) + ++Rank; + + LLVM_DEBUG(dbgs() << "Calculated Rank[" << I->getName() << "] = " << Rank + << "\n"); + + ValueRankMap[I] = Rank; + } else { + Worklist.push_back(RankWorkItem{I->getOperand(Item.OpNo), 0, 0}); + continue; + } - LLVM_DEBUG(dbgs() << "Calculated Rank[" << V->getName() << "] = " << Rank - << "\n"); + // Once the current use-def node has a known rank, carry that rank back to + // the parent expression and advance past the operand that led here. + Worklist.pop_back(); + if (Worklist.empty()) + return Rank; - return ValueRankMap[I] = Rank; + RankWorkItem &Parent = Worklist.back(); + Parent.Rank = std::max(Parent.Rank, Rank); + ++Parent.OpNo; + } } // Canonicalize constants to RHS. Otherwise, sort the operands by rank. From a1fcdd1a7a6943fca3d109a31d4d47d2cbd14e75 Mon Sep 17 00:00:00 2001 From: Jan Korous Date: Thu, 9 Jul 2026 14:59:20 -0700 Subject: [PATCH 033/125] [clang][ssaf] Add SARIF transformation-report format (#208327) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the built-in `TransformationReportFormat`, registered under the file extension `sarif`. The writer drives clang's existing `SarifDocumentWriter` (`clang/Basic/Sarif.h`) to produce a SARIF 2.1.0 JSON document. The tool driver name is `clang-ssaf`; the long `fullName` carries the transformation's name. Token-range `CharSourceRange`s are canonicalized to char ranges via `clang::Lexer::getAsCharRange` before being attached to results; invalid ranges (including default-constructed ones) are treated as "no location" — the writer omits the result's `locations` key rather than fabricating one. Source edits are not embedded in the report; the writer never emits a `fix` or `fixes` key. Anchored via `SSAFSARIFTransformationReportFormatAnchorSource` so static builds keep the registration. Assisted-By: Claude Opus 4.7 --- .../SARIFTransformationReportFormat.h | 50 +++++ .../SourceTransformation/CMakeLists.txt | 1 + .../SARIFTransformationReportFormat.cpp | 56 ++++++ .../ScalableStaticAnalysis/CMakeLists.txt | 1 + .../SourceTransformation/SARIFFormatTest.cpp | 185 ++++++++++++++++++ 5 files changed, 293 insertions(+) create mode 100644 clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h create mode 100644 clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp create mode 100644 clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp diff --git a/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h new file mode 100644 index 0000000000000..30b50d3c28fb2 --- /dev/null +++ b/clang/include/clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h @@ -0,0 +1,50 @@ +//===- SARIFTransformationReportFormat.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Built-in SARIF 2.1.0 transformation-report writer. Drives clang's existing +// `SarifDocumentWriter`; emits no `fix` keys (source edits live in the +// separate edit file). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H +#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H + +#include "clang/Basic/Sarif.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +class SourceManager; +} // namespace clang + +namespace clang::ssaf { + +struct ReportResult { + std::string RuleId; + clang::SarifResultLevel Level; + clang::CharSourceRange Range; + std::string Message; +}; + +struct ReportDocument { + std::string TransformationName; + const clang::SourceManager &SM; + std::vector Results; +}; + +/// Writes \p Doc to \p Path as a SARIF JSON document. +llvm::Error writeSARIFTransformationReport(const ReportDocument &Doc, + llvm::StringRef Path); + +} // namespace clang::ssaf + +#endif // LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_SOURCETRANSFORMATION_SARIFTRANSFORMATIONREPORTFORMAT_H diff --git a/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt b/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt index f46b6df1d0bdb..25db2fb7eca7d 100644 --- a/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt +++ b/clang/lib/ScalableStaticAnalysis/SourceTransformation/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangScalableStaticAnalysisSourceTransformation + SARIFTransformationReportFormat.cpp TransformationRegistry.cpp YAMLSourceEditFormat.cpp diff --git a/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp b/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp new file mode 100644 index 0000000000000..d5993d2c0345a --- /dev/null +++ b/clang/lib/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.cpp @@ -0,0 +1,56 @@ +//===- SARIFTransformationReportFormat.cpp --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h" +#include "clang/Basic/Sarif.h" +#include "clang/Basic/Version.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang; +using namespace ssaf; + +llvm::Error ssaf::writeSARIFTransformationReport(const ReportDocument &Doc, + llvm::StringRef Path) { + std::error_code EC; + llvm::raw_fd_ostream OS(Path, EC, llvm::sys::fs::OF_None); + if (EC) + return llvm::createStringError(EC, "failed to open '" + Path + "'"); + + clang::SarifDocumentWriter Writer(Doc.SM); + std::string LongToolName = + "clang ScalableStaticAnalysisFramework source transformation (" + + Doc.TransformationName + ")"; + Writer.createRun("clang-ssaf", LongToolName, CLANG_VERSION_STRING); + + llvm::StringMap RuleIndex; + for (const ReportResult &R : Doc.Results) { + if (RuleIndex.contains(R.RuleId)) + continue; + RuleIndex[R.RuleId] = + Writer.createRule(clang::SarifRule::create().setRuleId(R.RuleId)); + } + + for (const ReportResult &R : Doc.Results) { + clang::SarifResult Result = clang::SarifResult::create(RuleIndex[R.RuleId]) + .setRuleId(R.RuleId) + .setDiagnosticMessage(R.Message) + .setDiagnosticLevel(R.Level); + if (R.Range.isValid()) + Result = Result.addLocations({R.Range}); + Writer.appendResult(Result); + } + + llvm::json::Value Document(Writer.createDocument()); + OS << llvm::formatv("{0:2}", Document) << "\n"; + return llvm::Error::success(); +} diff --git a/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt b/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt index 972287132b36d..08f82876aabf1 100644 --- a/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt +++ b/clang/unittests/ScalableStaticAnalysis/CMakeLists.txt @@ -27,6 +27,7 @@ add_distinct_clang_unittest(ClangScalableAnalysisTests Serialization/JSONFormatTest/TUSummaryTest.cpp SourceTransformation/EmitterTest.cpp SourceTransformation/RegistryTest.cpp + SourceTransformation/SARIFFormatTest.cpp SourceTransformation/YAMLFormatTest.cpp SummaryData/SummaryDataTest.cpp SummaryNameTest.cpp diff --git a/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp b/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp new file mode 100644 index 0000000000000..1870f834178cc --- /dev/null +++ b/clang/unittests/ScalableStaticAnalysis/SourceTransformation/SARIFFormatTest.cpp @@ -0,0 +1,185 @@ +//===- SARIFFormatTest.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/Sarif.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/Version.h" +#include "clang/ScalableStaticAnalysis/SourceTransformation/SARIFTransformationReportFormat.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "llvm/Testing/Support/Error.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; +using namespace ssaf; + +namespace { + +struct TempPath { + SmallString<128> Path; + + TempPath(StringRef Suffix) { + sys::fs::createUniquePath("ssaf-sarif-%%%%%%." + Suffix, Path, + /*MakeAbsolute=*/true); + } + ~TempPath() { sys::fs::remove(Path); } +}; + +class SARIFFormatTest : public ::testing::Test { +protected: + SARIFFormatTest() + : Diags(DiagnosticIDs::create(), DiagOpts, new IgnoringDiagConsumer()), + VFS(makeIntrusiveRefCnt()), + FileMgr(FileSystemOptions(), VFS), SourceMgr(Diags, FileMgr) {} + + json::Value writeAndParse(const ReportDocument &Doc) { + TempPath TP("sarif"); + EXPECT_THAT_ERROR(writeSARIFTransformationReport(Doc, TP.Path), + Succeeded()); + auto BufferOrErr = MemoryBuffer::getFile(TP.Path); + EXPECT_TRUE(static_cast(BufferOrErr)); + auto ParsedOrErr = json::parse((*BufferOrErr)->getBuffer()); + EXPECT_THAT_EXPECTED(ParsedOrErr, Succeeded()); + return std::move(*ParsedOrErr); + } + + DiagnosticOptions DiagOpts; + DiagnosticsEngine Diags; + IntrusiveRefCntPtr VFS; + FileManager FileMgr; + SourceManager SourceMgr; +}; + +TEST_F(SARIFFormatTest, ToolDriverNameAndVersion) { + ReportDocument Doc{"my-transformation", SourceMgr, {}}; + json::Value V = writeAndParse(Doc); + + const json::Object *Root = V.getAsObject(); + ASSERT_NE(Root, nullptr); + const json::Array *Runs = Root->getArray("runs"); + ASSERT_NE(Runs, nullptr); + ASSERT_EQ(Runs->size(), 1u); + const json::Object *Driver = + (*Runs)[0].getAsObject()->getObject("tool")->getObject("driver"); + ASSERT_NE(Driver, nullptr); + EXPECT_EQ(*Driver->getString("name"), "clang-ssaf"); + EXPECT_NE(Driver->getString("fullName")->find("my-transformation"), + StringRef::npos); + EXPECT_EQ(*Driver->getString("version"), CLANG_VERSION_STRING); +} + +TEST_F(SARIFFormatTest, LevelMapping) { + ReportDocument Doc{"t", + SourceMgr, + { + {"r-note", clang::SarifResultLevel::Note, {}, "n"}, + {"r-warn", clang::SarifResultLevel::Warning, {}, "w"}, + {"r-error", clang::SarifResultLevel::Error, {}, "e"}, + {"r-none", clang::SarifResultLevel::None, {}, "x"}, + }}; + json::Value V = writeAndParse(Doc); + + const json::Array *Results = + V.getAsObject()->getArray("runs")->front().getAsObject()->getArray( + "results"); + ASSERT_NE(Results, nullptr); + ASSERT_EQ(Results->size(), 4u); + EXPECT_EQ(*(*Results)[0].getAsObject()->getString("level"), "note"); + EXPECT_EQ(*(*Results)[1].getAsObject()->getString("level"), "warning"); + EXPECT_EQ(*(*Results)[2].getAsObject()->getString("level"), "error"); + EXPECT_EQ(*(*Results)[3].getAsObject()->getString("level"), "none"); +} + +TEST_F(SARIFFormatTest, InvalidRangeOmitsLocations) { + ReportDocument Doc{ + "t", + SourceMgr, + {{"r", clang::SarifResultLevel::Note, clang::CharSourceRange{}, "msg"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + EXPECT_EQ(Result->get("locations"), nullptr); +} + +TEST_F(SARIFFormatTest, EmptyResultsValidDocument) { + ReportDocument Doc{"t", SourceMgr, {}}; + json::Value V = writeAndParse(Doc); + const json::Object *Run = + V.getAsObject()->getArray("runs")->front().getAsObject(); + // SARIF allows the results array to be absent or empty for an empty run. + if (const json::Array *Results = Run->getArray("results")) + EXPECT_TRUE(Results->empty()); +} + +TEST_F(SARIFFormatTest, NoFixKey) { + ReportDocument Doc{ + "t", SourceMgr, {{"r", clang::SarifResultLevel::Warning, {}, "msg"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + EXPECT_EQ(Result->get("fix"), nullptr); + EXPECT_EQ(Result->get("fixes"), nullptr); +} + +TEST_F(SARIFFormatTest, EmptyRuleIdAccepted) { + ReportDocument Doc{ + "t", SourceMgr, {{"", clang::SarifResultLevel::Note, {}, "m"}}}; + json::Value V = writeAndParse(Doc); + const json::Object *Result = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getArray("results") + ->front() + .getAsObject(); + ASSERT_NE(Result->getString("ruleId"), std::nullopt); + EXPECT_EQ(*Result->getString("ruleId"), ""); +} + +TEST_F(SARIFFormatTest, DistinctRuleIdsDeduplicated) { + ReportDocument Doc{"t", + SourceMgr, + { + {"a", clang::SarifResultLevel::Note, {}, "m1"}, + {"b", clang::SarifResultLevel::Note, {}, "m2"}, + {"a", clang::SarifResultLevel::Note, {}, "m3"}, + }}; + json::Value V = writeAndParse(Doc); + const json::Array *Rules = V.getAsObject() + ->getArray("runs") + ->front() + .getAsObject() + ->getObject("tool") + ->getObject("driver") + ->getArray("rules"); + ASSERT_NE(Rules, nullptr); + EXPECT_EQ(Rules->size(), 2u); +} + +} // namespace From 3bdf536992084d0a30efc65f8198549b3a824c56 Mon Sep 17 00:00:00 2001 From: Walnut Date: Thu, 9 Jul 2026 17:04:07 -0500 Subject: [PATCH 034/125] [lldb] Use `llvm::APInt` for `VariantMember` Discriminants (#188487) resolves #177812 It currently uses a `uint32_t` even though Rust can output 64- and 128-bit discriminants. This became a more obvious issue when Rust started niche-optimizing based on the capacity of strings (which are `NoHighBit` values, guaranteed to be less than `u64::MAX / 2`), rather than the `NonNull` heap pointer. With this optimization, the `None` variant of strings is 9223372036854775808, which LLDB truncates to 0. This means whenever the capacity is 0 (e.g. `Some(String::new())`, LLDB will mistakenly read it as the `None` variant. Additionally, when trying to determine the `None` variant, lldb will read the discr from memory correctly (9223372036854775808), and the visualizer scripts will compare that to the value in the variant name (`$variant$0`), see that it doesn't match, and incorrectly decides that it must not be the `None` variant. This patch simply swaps the `uint32_t` with an `llvm::APInt`. Sample program: ```rust #[repr(u128)] enum BigDiscr { Value(u64), None = 0x16151413121110090807060504030201, } fn main() { let big_discr_none = BigDiscr::None; let big_disr_some = BigDiscr::Value(31); let some_string = Some(String::from("asdf")); let some_empty_string = Some(String::new()); let none_string: Option = Option::None; println!("Hello world!"); // break } ``` New output without visualizers: ```txt (sample::BigDiscr) big_discr_none = { $variants$ = { $variant$0 = { $discr$ = 29352461300415899028694309177919734273 value = (__0 = 0) } $variant$29352461300415899028694309177919734273 = ($discr$ = 29352461300415899028694309177919734273, value = sample::BigDiscr::None:128 @ 0x000000710a7ff7d0) } } (sample::BigDiscr) big_disr_some = { $variants$ = { $variant$0 = { $discr$ = 0 value = (__0 = 31) } $variant$29352461300415899028694309177919734273 = ($discr$ = 0, value = sample::BigDiscr::None:128 @ 0x000000710a7ff7f0) } } (core::option::Option) some_string = { $variants$ = { $variant$9223372036854775808 = ($discr$ = 4, value = core::option::Option::None:64 @ 0x000000710a7ff750) $variant$ = { value = { __0 = { vec = {...} } } } } } (core::option::Option) some_empty_string = { $variants$ = { $variant$9223372036854775808 = ($discr$ = 0, value = core::option::Option::None:64 @ 0x000000710a7ff780) $variant$ = { value = { __0 = { vec = {...} } } } } } (core::option::Option) none_string = { $variants$ = { $variant$9223372036854775808 = ($discr$ = 9223372036854775808, value = core::option::Option::None:64 @ 0x000000710a7ff7b8) $variant$ = { value = { __0 = { vec = {...} } } } } } ``` New output with Rust's current visualizers: ```txt # this one is incorrect because the visualizer scripts are wrong, not because of LLDB. # the scripts use `GetValue()`, which returns a 64 bit number. They can be modified # on Rust's end to use `GetData()` instead. The rest work as expected (sample::BigDiscr) big_discr_none = Value(0) { 0 = 0 } (sample::BigDiscr) big_disr_some = Value(31) { 0 = 31 } (core::option::Option) some_string = Some("asdf") { 0 = "asdf" { [0] = 'a' [1] = 's' [2] = 'd' [3] = 'f' } } (core::option::Option) some_empty_string = Some("") { 0 = "" } ``` --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 44 +- .../unittests/SymbolFile/DWARF/CMakeLists.txt | 3 +- .../DWARF/DWARFASTParserClangTests.cpp | 36 +- .../Inputs/DW_TAG_variant_rust-test.yaml | 871 ++++++++++++++++++ 4 files changed, 945 insertions(+), 9 deletions(-) create mode 100644 lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 0506b7d4da40f..b60f1d9e41958 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -13,6 +13,7 @@ #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" #include "DWARFDefines.h" +#include "DWARFFormValue.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" @@ -2572,7 +2573,7 @@ struct VariantMember { explicit VariantMember(DWARFDIE &die, ModuleSP module_sp); bool IsDefault() const; - std::optional discr_value; + std::optional discr_value; DWARFFormValue type_ref; ConstString variant_name; uint32_t byte_offset; @@ -2600,8 +2601,34 @@ bool VariantMember::IsDefault() const { return !discr_value; } VariantMember::VariantMember(DWARFDIE &die, lldb::ModuleSP module_sp) { assert(die.Tag() == llvm::dwarf::DW_TAG_variant); - this->discr_value = - die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value); + + DWARFFormValue discr_form; + die.GetDIE()->GetAttributeValue(die.GetCU(), DW_AT_discr_value, discr_form); + + // Rust can output 128-bit discriminants (e.g. NonNull) as + // `DW_FORM_block1`. There is a `data16` dwarf form, but DWARFFormValue treats + // it as a BlockData anyway. Handling is included for it just in case rust's + // output changes to the `data16` form. + dw_form_t form = discr_form.Form(); + if ((form == DW_FORM_block1 && discr_form.Unsigned() == 16) || + form == DW_FORM_data16) { + const uint8_t *block_data = discr_form.BlockData(); + + DataExtractor extractor(block_data, 16, die.GetCU()->GetByteOrder(), + die.GetCU()->GetAddressByteSize()); + lldb::offset_t offset = 0; + uint64_t lo = extractor.GetU64(&offset); + uint64_t hi = extractor.GetU64(&offset); + uint64_t words[] = {lo, hi}; + this->discr_value = llvm::APInt(128, words); + } else { + if (auto result = + die.GetAttributeValueAsOptionalUnsigned(DW_AT_discr_value)) { + this->discr_value = llvm::APInt(sizeof(uint64_t) * 8, result.value()); + } else { + this->discr_value = std::nullopt; + }; + } for (auto child_die : die.children()) { switch (child_die.Tag()) { @@ -3838,9 +3865,14 @@ void DWARFASTParserClang::ParseRustVariantPart( m_ast.CompleteTagDeclarationDefinition(field_type); - auto name = has_discriminant - ? llvm::formatv("$variant${0}", member.discr_value.value()) - : std::string("$variant$"); + auto name = std::string("$variant$"); + if (has_discriminant) { + // u128::MAX = 340282366920938463463374607431768211455 which is 39 digits + // long + 1 for null terminator. + llvm::SmallString<40> discr_str; + member.discr_value.value().toStringUnsigned(discr_str); + name.append(discr_str.c_str()); + } auto variant_decl = m_ast.AddFieldToRecordType( inner_holder, llvm::StringRef(name), field_type, 0); diff --git a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt index 88492188e794b..185cad60f74d9 100644 --- a/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/unittests/SymbolFile/DWARF/CMakeLists.txt @@ -28,6 +28,7 @@ add_lldb_unittest(SymbolFileDWARFTests set(test_inputs test-dwarf.exe DW_AT_default_value-test.yaml - DW_AT_spec_decl_exists-test.yaml) + DW_AT_spec_decl_exists-test.yaml + DW_TAG_variant_rust-test.yaml) add_unittest_inputs(SymbolFileDWARFTests "${test_inputs}") diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp index a95d6ecfab790..4d4dc57816694 100644 --- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -667,14 +667,14 @@ TEST_F(DWARFASTParserClangTests, TestUniqueDWARFASTTypeMap_CppInsertMapFind) { debug_str: - Foo - debug_line: + debug_line: - Version: 4 MinInstLength: 1 MaxOpsPerInst: 1 DefaultIsStmt: 1 LineBase: 0 LineRange: 0 - Files: + Files: - Name: main.cpp DirIdx: 0 ModTime: 0 @@ -2118,3 +2118,35 @@ TEST_F(DWARFASTParserClangTests, EXPECT_EQ(type_sp->GetName(), "Bar"); EXPECT_EQ(type_sp->GetForwardCompilerType().GetTypeName(), "Foo::Bar"); } + +TEST_F(DWARFASTParserClangTests, TestRustVariantMember) { + // Tests that 128-bit discriminants are output to variant names correctly. + auto yamldata = llvm::MemoryBuffer::getFile( + GetInputFilePath("DW_TAG_variant_rust-test.yaml"), /*IsText=*/true); + ASSERT_TRUE(yamldata); + + DWARFASTParserClangYAMLTester tester(yamldata->get()->getBuffer()); + + auto &ts_clang = tester.GetTypeSystem(); + auto *symbol_file = ts_clang.GetSymbolFile(); + + TypeQuery query{ConstString("BigDiscr")}; + TypeResults result{}; + symbol_file->FindTypes(query, result); + + auto type = result.GetFirstType(); + auto enum_type = type.get()->GetFullCompilerType(); + std::string f_name; + auto all_variants = + enum_type.GetFieldAtIndex(0, f_name, nullptr, nullptr, nullptr); + ASSERT_EQ(f_name, "$variants$"); + + f_name.clear(); + all_variants.GetFieldAtIndex(0, f_name, nullptr, nullptr, nullptr); + ASSERT_EQ(f_name, "$variant$0"); + + all_variants.GetFieldAtIndex(1, f_name, nullptr, nullptr, nullptr); + // 0x16151413121110090807060504030201 == + // 29352461300415899028694309177919734273 + ASSERT_EQ(f_name, "$variant$29352461300415899028694309177919734273"); +} diff --git a/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml b/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml new file mode 100644 index 0000000000000..b7089e362cf13 --- /dev/null +++ b/lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml @@ -0,0 +1,871 @@ +# Below code compiled with rustc src/main.rs --target=x86_64-unknown-linux-gnu -g -C panic=abort +# +# #![no_std] +# #![no_main] +# +# #[allow(unused)] +# #[repr(u128)] +# enum BigDiscr { +# Value(u64), +# None = 0x16151413121110090807060504030201, +# } +# +# fn use_it(_: &BigDiscr) {} +# +# #[panic_handler] +# fn panic(_info: &core::panic::PanicInfo) -> ! { +# loop {} +# } +# +# #[unsafe(no_mangle)] +# extern "C" fn main() { +# let none = BigDiscr::None; +# let some = BigDiscr::Value(31); +# +# use_it(&none); +# use_it(&some); +# } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x4 + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 48897C24F8EBFE + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 48897C24F8C3 + - Name: .text.main + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 4883EC4848B80910111213141516488944240848B801020304050607084889042448C74424301F00000048C74424280000000048C7442420000000004889E7E800000000488D7C2420E8000000004883C448C3 + - Name: .debug_gdb_scripts + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 016764625F6C6F61645F727573745F7072657474795F7072696E746572732E707900 + - Name: .debug_abbrev + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 011101250E1305030E10171B0E110155170000023901030E0000032E011101120640186E0E030E3A0B3B0B87011900000405000218030E3A0B3B0B49130000052E011101120640186E0E030E3A0B3B0B000006050002183A0B3B0B49130000072E01110112064018030E3A0B3B0B3F190000080B011101120600000934000218030E88010F3A0B3B0B491300000A1301030E0B0B320B88010F00000B3301151300000C0D00491388010F380B341900000D1901160A00000E0D00030E491388010F380B00000F0D00030E491388010F380B320B0000101300030E0B0B320B88010F0000110F004913030E330600001219010000131901160B0000142F004913030E0000152400030E3E0B0B0B00001615014913000017050049130000181301030E0B0B88010F0000190F004913330600001A1300030E0B0B88010F00001B0101491300001C21004913220D370B00001D2400030E0B0B3E0B000000 + - Name: .debug_info + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 5F0500000400000000000801000000001C0000000000000000000000000000000000000000000000000002000000000300000000000000000700000001570000000000000000010E0402917800000000010E3B010000000500000000000000000600000001570000000000000000010B06029178010B4E050000000700000000000000005300000001570000000001130800000000000000002D0000000902910000000000100114CB000000080000000000000000120000000902912000000000100115CB0000000000000A000000002003100BD80000000C5B05000010000D10000000000000000000000000000000000E000000001C0100001000000D10010203040506070809101112131415160E0000000031010000100000000A000000002003100F00000000320400000810030010000000002003100000115701000000000000000000000200000000020000000002000000000A000000001801080F00000000110400000800030F00000000F50400000808030F00000000470500000110030F0000000047050000011103000002000000000A000000001801080F00000000400300000800030F00000000770400000410030F00000000770400000414030F00000000FD03000001180300000002000000000A000000001001080F00000000E60200000800030F00000000040300000808030002000000000A000000001001080F0000000011020000080003000A000000001003080B1E0200000C320400000800120E000000004102000008000013000E000000006E020000080000000A000000001003080F00000000220300000800030F000000004D0400000808030F00000000EB030000011003000A000000001003080F000000007E04000002080300000010000000000001010A000000001801080F00000000AE0200000410030F0000000085040000080003000A000000000801040F00000000770400000400030F000000007E0400000204030F000000007E0400000206030000020000000002000000000A00000000080108141E040000000000000F0000000025040000080003000A0000000008010814FC010000000000000F00000000E8040000080003000A000000000801081439040000000000000F0000000040040000080003000A00000000100108141E040000000000000F000000000205000008000300000002000000000A000000000101010B720300000C1E040000010013000E000000009603000001000013010E00000000BD030000010000000A000000000101011439040000000000001485020000000000000F0000000039040000010101000A000000000101011439040000000000001485020000000000000F000000008502000001010100000002000000000A0000000000010114DB04000000000000000A0000000000010114290500000000000000000011D6010000000000000000000015000000000701111E0400000000000000000000150000000007081500000000070011390400000000000000000000115A040000000000000000000016650300001722030000176A04000000118D02000000000000000000001500000000070415000000000702180000000010080E00000000A304000008000E00000000B304000008080019AC040000000000001A00000000000111C004000000000000000000001BCD0400001CD4040000000600150000000007081D0000000008071139040000000000000000000011FC010000000000000000000011960100000000000000000000180000000010080E000000002005000008000E00000000CD040000080800191E04000000000000180000000010080E000000002005000008000E00000000CD0400000808001500000000020111CB00000000000000000000001500000000071000 + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x1 + EntSize: 0x1 + Content: 0072757374632076657273696F6E20312E39332E30202832353462353936303720323032362D30312D31392900 + - Name: .note.GNU-stack + Type: SHT_PROGBITS + AddressAlign: 0x1 + - Name: .eh_frame + Type: SHT_X86_64_UNWIND + Flags: [ SHF_ALLOC ] + AddressAlign: 0x8 + Content: 1400000000000000017A5200017810011B0C070890010000100000001C00000000000000070000000000000010000000300000000000000006000000000000001400000044000000000000005300000000440E50024E0E08 + - Name: .debug_line + Type: SHT_PROGBITS + AddressAlign: 0x1 + Content: 79000000040023000000010101FB0E0D00010101010000000100000173726300006D61696E2E727300010000000009020000000000000000030D0105050A5902020001010009020000000000000000030A01051B0A580201000101000902000000000000000003120105100AD7082F050508A08305020B9F0205000101 + - Name: .rela.text.main + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .text.main + Relocations: + - Offset: 0x40 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PLT32 + Addend: -4 + - Offset: 0x4A + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PLT32 + Addend: -4 + - Name: .rela.debug_info + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_info + Relocations: + - Offset: 0x6 + Symbol: .debug_abbrev + Type: R_X86_64_32 + - Offset: 0xC + Symbol: .debug_str + Type: R_X86_64_32 + - Offset: 0x12 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 57 + - Offset: 0x16 + Symbol: .debug_line + Type: R_X86_64_32 + - Offset: 0x1A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 99 + - Offset: 0x26 + Symbol: .debug_ranges + Type: R_X86_64_32 + - Offset: 0x2B + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 147 + - Offset: 0x30 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x3E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 152 + - Offset: 0x42 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 199 + - Offset: 0x4C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 248 + - Offset: 0x58 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x66 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 205 + - Offset: 0x6A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 241 + - Offset: 0x7C + Symbol: .text.main + Type: R_X86_64_64 + - Offset: 0x8A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 147 + - Offset: 0x91 + Symbol: .text.main + Type: R_X86_64_64 + Addend: 33 + - Offset: 0xA1 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1193 + - Offset: 0xAD + Symbol: .text.main + Type: R_X86_64_64 + Addend: 60 + - Offset: 0xBD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1198 + - Offset: 0xCC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1168 + - Offset: 0xF2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1157 + - Offset: 0x110 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1163 + - Offset: 0x11D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1157 + - Offset: 0x125 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x132 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1163 + - Offset: 0x140 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1116 + - Offset: 0x149 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 254 + - Offset: 0x14E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 199 + - Offset: 0x153 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 259 + - Offset: 0x158 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1106 + - Offset: 0x160 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 270 + - Offset: 0x16C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 929 + - Offset: 0x178 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1071 + - Offset: 0x184 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1087 + - Offset: 0x192 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 929 + - Offset: 0x197 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1029 + - Offset: 0x19F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 938 + - Offset: 0x1AB + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 987 + - Offset: 0x1B7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 992 + - Offset: 0x1C3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 996 + - Offset: 0x1D2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 278 + - Offset: 0x1D7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 897 + - Offset: 0x1DF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 282 + - Offset: 0x1EB + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 339 + - Offset: 0x1F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 344 + - Offset: 0x1FD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 824 + - Offset: 0x205 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 347 + - Offset: 0x212 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 811 + - Offset: 0x227 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 354 + - Offset: 0x235 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 805 + - Offset: 0x242 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 354 + - Offset: 0x24A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 366 + - Offset: 0x256 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 397 + - Offset: 0x262 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 767 + - Offset: 0x26F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 805 + - Offset: 0x277 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x286 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 417 + - Offset: 0x28E + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 614 + - Offset: 0x296 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 462 + - Offset: 0x2A2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 518 + - Offset: 0x2AF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 500 + - Offset: 0x2B7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 470 + - Offset: 0x2C3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 480 + - Offset: 0x2CF + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 490 + - Offset: 0x2DD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 291 + - Offset: 0x2E2 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 295 + - Offset: 0x2E7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 327 + - Offset: 0x2F3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x2F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x305 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 864 + - Offset: 0x311 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x316 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x323 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 385 + - Offset: 0x32F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x334 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x341 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 974 + - Offset: 0x34D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x352 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x361 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 407 + - Offset: 0x366 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 433 + - Offset: 0x37C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 414 + - Offset: 0x38A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 429 + - Offset: 0x397 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 414 + - Offset: 0x3A3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3AC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 423 + - Offset: 0x3B1 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x3BE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 429 + - Offset: 0x3CA + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3D3 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 423 + - Offset: 0x3D8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 425 + - Offset: 0x3E7 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 777 + - Offset: 0x3EC + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 788 + - Offset: 0x3F8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x3FE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1011 + - Offset: 0x40A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 307 + - Offset: 0x416 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 907 + - Offset: 0x41F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 304 + - Offset: 0x42A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 317 + - Offset: 0x433 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 350 + - Offset: 0x43A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 372 + - Offset: 0x445 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 375 + - Offset: 0x452 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 650 + - Offset: 0x46F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 624 + - Offset: 0x478 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 476 + - Offset: 0x47F + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 486 + - Offset: 0x486 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 588 + - Offset: 0x48D + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 309 + - Offset: 0x498 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 543 + - Offset: 0x4AD + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 522 + - Offset: 0x4B8 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 576 + - Offset: 0x4CE + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 550 + - Offset: 0x4D5 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 556 + - Offset: 0x4E0 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 784 + - Offset: 0x4ED + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 833 + - Offset: 0x4FA + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1038 + - Offset: 0x503 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 963 + - Offset: 0x50A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 947 + - Offset: 0x515 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 956 + - Offset: 0x52A + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1006 + - Offset: 0x531 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 947 + - Offset: 0x53C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 956 + - Offset: 0x548 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1082 + - Offset: 0x553 + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1177 + - Offset: 0x55C + Symbol: .debug_str + Type: R_X86_64_32 + Addend: 1152 + - Name: .rela.debug_aranges + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_aranges + Relocations: + - Offset: 0x6 + Symbol: .debug_info + Type: R_X86_64_32 + - Offset: 0x10 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x20 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x30 + Symbol: .text.main + Type: R_X86_64_64 + - Name: .rela.debug_ranges + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_ranges + Relocations: + - Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x8 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + Addend: 7 + - Offset: 0x10 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x18 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + Addend: 6 + - Offset: 0x20 + Symbol: .text.main + Type: R_X86_64_64 + - Offset: 0x28 + Symbol: .text.main + Type: R_X86_64_64 + Addend: 83 + - Name: .rela.eh_frame + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .eh_frame + Relocations: + - Offset: 0x20 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_PC32 + - Offset: 0x34 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_PC32 + - Offset: 0x48 + Symbol: .text.main + Type: R_X86_64_PC32 + - Name: .rela.debug_line + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .debug_line + Relocations: + - Offset: 0x30 + Symbol: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: R_X86_64_64 + - Offset: 0x47 + Symbol: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: R_X86_64_64 + - Offset: 0x5E + Symbol: .text.main + Type: R_X86_64_64 + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: .text + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + - Name: .text.main + - Name: .rela.text.main + - Name: .debug_gdb_scripts + - Name: .debug_abbrev + - Name: .debug_info + - Name: .rela.debug_info + - Name: .debug_aranges + - Name: .rela.debug_aranges + - Name: .debug_ranges + - Name: .rela.debug_ranges + - Name: .debug_str + - Name: .comment + - Name: .note.GNU-stack + - Name: .eh_frame + - Name: .rela.eh_frame + - Name: .debug_line + - Name: .rela.debug_line + - Name: .symtab +Symbols: + - Name: main.9b5cc465332d101d-cgu.0 + Type: STT_FILE + Index: SHN_ABS + - Name: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: STT_SECTION + Section: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - Name: .text._ZN4main6use_it17h7beb6f96865c87acE + Type: STT_SECTION + Section: .text._ZN4main6use_it17h7beb6f96865c87acE + - Name: _ZN4main6use_it17h7beb6f96865c87acE + Type: STT_FUNC + Section: .text._ZN4main6use_it17h7beb6f96865c87acE + Size: 0x6 + - Name: .text.main + Type: STT_SECTION + Section: .text.main + - Name: .debug_abbrev + Type: STT_SECTION + Section: .debug_abbrev + - Name: .debug_info + Type: STT_SECTION + Section: .debug_info + - Name: .debug_ranges + Type: STT_SECTION + Section: .debug_ranges + - Name: .debug_str + Type: STT_SECTION + Section: .debug_str + - Name: .debug_line + Type: STT_SECTION + Section: .debug_line + - Name: _RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Type: STT_FUNC + Section: .text._RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + Binding: STB_GLOBAL + Size: 0x7 + Other: [ STV_HIDDEN ] + - Name: main + Type: STT_FUNC + Section: .text.main + Binding: STB_GLOBAL + Size: 0x53 + - Name: __rustc_debug_gdb_scripts_section__ + Type: STT_OBJECT + Section: .debug_gdb_scripts + Binding: STB_WEAK + Size: 0x22 +DWARF: + debug_str: + - 'clang LLVM (rustc version 1.93.0 (254b59607 2026-01-19))' + - 'src/main.rs\@\main.9b5cc465332d101d-cgu.0' + - 'C:\Coding\NotMyCode\llvm_patches\llvm-project\z' + - main + - _RNvCshXwFllX56pT_7___rustc17rust_begin_unwind + - panic + - _ZN4main6use_it17h7beb6f96865c87acE + - use_it + - _info + - core + - panic_info + - message + - fmt + - template + - ptr + - non_null + - u8 + - T + - pointer + - '*const u8' + - 'NonNull' + - args + - rt + - ty + - u64 + - Placeholder + - value + - '()' + - '*const ()' + - 'NonNull<()>' + - formatter + - result + - Ok + - Error + - E + - __0 + - Err + - 'Result<(), core::fmt::Error>' + - options + - flags + - u32 + - width + - u16 + - precision + - FormattingOptions + - buf + - 'dyn core::fmt::Write' + - vtable + - usize + - __ARRAY_SIZE_TYPE__ + - '&[usize; 6]' + - '&mut dyn core::fmt::Write' + - Formatter + - '&mut core::fmt::Formatter' + - 'unsafe fn(core::ptr::non_null::NonNull<()>, &mut core::fmt::Formatter) -> core::result::Result<(), core::fmt::Error>' + - _lifetime + - marker + - '&()' + - 'PhantomData<&()>' + - Count + - ArgumentType + - Argument + - '*const core::fmt::rt::Argument' + - 'NonNull' + - Arguments + - '&core::fmt::Arguments' + - location + - filename + - data_ptr + - length + - '*const str' + - 'NonNull' + - line + - col + - _filename + - '&str' + - 'PhantomData<&str>' + - Location + - '&core::panic::location::Location' + - can_unwind + - bool + - force_no_backtrace + - PanicInfo + - '&core::panic::panic_info::PanicInfo' + - u128 + - Value + - None + - BigDiscr + - '&main::BigDiscr' + - none + - some + debug_aranges: + - Length: 0x4C + Version: 2 + CuOffset: 0x0 + AddressSize: 0x8 + Descriptors: + - Address: 0x0 + Length: 0x7 + - Address: 0x0 + Length: 0x6 + - Address: 0x0 + Length: 0x53 + debug_ranges: + - Offset: 0x0 + AddrSize: 0x8 + Entries: [] + - Offset: 0x10 + AddrSize: 0x8 + Entries: [] + - Offset: 0x20 + AddrSize: 0x8 + Entries: [] + - Offset: 0x30 + AddrSize: 0x8 + Entries: [] +... From 0538275eca10798aa0d0dd6261f11fbc7cc9e99e Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Fri, 10 Jul 2026 00:12:53 +0200 Subject: [PATCH 035/125] [lldb] Don't add the same module to a target twice (#208472) `Target::GetOrCreateModule` uses `Append`, so a module already in the target could be added again. Then `RemoveModule` dropped only one, keeping the module (and its memory-mapped file) alive. On Windows that mapped file can't be deleted, causing `TestReplaceDLL.py` to fail with `LLDB_USE_LLDB_SERVER=1`. This patch uses `AppendIfNeeded` instead. rdar://181797592 --- lldb/source/Target/Target.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 4084d72ee1317..daa1b1c43efa8 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2659,8 +2659,10 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &orig_module_spec, } } - if (replaced_modules.empty()) - m_images.Append(module_sp, notify); + if (replaced_modules.empty()) { + if (!m_images.AppendIfNeeded(module_sp, notify) && notify) + NotifyModuleAdded(m_images, module_sp); + } for (ModuleSP &old_module_sp : replaced_modules) { auto old_module_wp = old_module_sp->weak_from_this(); From b0627c0c94bd93b6e9e6dcedb2e7bfa69e6f4052 Mon Sep 17 00:00:00 2001 From: Kaitlin Peng Date: Thu, 9 Jul 2026 15:21:43 -0700 Subject: [PATCH 036/125] [HLSL] Reject unbounded resource array and noinline function resource parameters (#208111) Fixes #180808. This issue involved two bugs: - `noinline` functions accepted resource parameters in the frontend, which crashed the backend since valid DXIL cannot be generated for resources passed across a function call. This change adds a new check in `SemaDecl.cpp` that rejects resource parameters on `noinline` functions, as well as a new `resource_params_noinline.hlsl` test. - The check for incomplete resource array parameters queried the array's element type to decide if it was a resource. When the parameter was the first use of the resource type, the element was still incomplete and wouldn't register as a resource, so the check would be skipped and the compiler would later crash. This change fixes the check to now force element completion with `isCompleteType` before querying the type, and updates `unbounded_resource_arrays.hlsl` to test this. This change also fixes the `unbounded_resource_arrays.hlsl` test in general; the `not` in the RUN command was inverting the result and hiding an actual failure (one of the expected error messages was misspelled). Assisted by: Github Copilot --- .../clang/Basic/DiagnosticSemaKinds.td | 2 + clang/lib/Sema/SemaDecl.cpp | 35 +++++++++++-- .../Resources/resource_params_noinline.hlsl | 20 ++++++++ .../Resources/unbounded_resource_arrays.hlsl | 50 +++++++++++-------- 4 files changed, 81 insertions(+), 26 deletions(-) create mode 100644 clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 09a533ed7dd11..09951730e1570 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13835,6 +13835,8 @@ def note_hlsl_resource_range_here: Note<"overlapping resource range here">; def err_hlsl_incomplete_resource_array_in_function_param: Error< "incomplete resource array in a function parameter">; +def err_hlsl_resource_param_in_noinline_function: Error< + "resource type %0 cannot be used as a parameter of a noinline function">; def err_hlsl_assign_to_global_resource: Error< "assignment to global resource variable %0 is not allowed">; def warn_hlsl_assigning_local_resource_is_not_unique diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2fc4fac6d5351..d1ddd3f6a1cc2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11046,6 +11046,25 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (NewFD->hasAttr()) HLSL().CheckEntryPoint(NewFD); + + // Resources cannot be passed to functions that are not inlined. + if (const NoInlineAttr *NoInline = NewFD->getAttr()) { + for (const ParmVarDecl *PVD : NewFD->parameters()) { + QualType ParamTy = PVD->getType().getNonReferenceType(); + QualType EltTy = Context.getBaseElementType(ParamTy); + // `isCompleteType` forces completion of the element type without + // reporting an error (diagnosed elsewhere) so the resource parameter + // check is valid. + if (!EltTy->isDependentType() && + isCompleteType(PVD->getLocation(), EltTy) && + ParamTy->isHLSLIntangibleType()) { + Diag(PVD->getLocation(), + diag::err_hlsl_resource_param_in_noinline_function) + << ParamTy; + Diag(NoInline->getLocation(), diag::note_attribute); + } + } + } } // If this is the first declaration of a library builtin function, add @@ -15770,11 +15789,17 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D, } // Incomplete resource arrays are not allowed as function parameters in HLSL - if (getLangOpts().HLSL && parmDeclType->isIncompleteArrayType() && - parmDeclType->isHLSLResourceRecordArray()) { - Diag(D.getIdentifierLoc(), - diag::err_hlsl_incomplete_resource_array_in_function_param); - D.setInvalidType(true); + if (getLangOpts().HLSL && parmDeclType->isIncompleteArrayType()) { + QualType EltTy = Context.getBaseElementType(parmDeclType); + // `isCompleteType` forces completion of the element type so the resource + // check is valid. + if (!EltTy->isDependentType() && + isCompleteType(D.getIdentifierLoc(), EltTy) && + parmDeclType->isHLSLResourceRecordArray()) { + Diag(D.getIdentifierLoc(), + diag::err_hlsl_incomplete_resource_array_in_function_param); + D.setInvalidType(true); + } } // Temporarily put parameter variables in the translation unit, not diff --git a/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl b/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl new file mode 100644 index 0000000000000..fbe0a7b070be4 --- /dev/null +++ b/clang/test/SemaHLSL/Resources/resource_params_noinline.hlsl @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -fsyntax-only -finclude-default-header %s -verify + +// expected-error@+2 {{resource type 'RWBuffer' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_param(RWBuffer A) {} + +// expected-error@+2 {{resource type 'RWBuffer[4]' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_array_param(RWBuffer A[4]) {} + +struct MyStruct { + RWBuffer A; +}; +// expected-error@+2 {{resource type 'MyStruct' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) float resource_struct_param(MyStruct S) {} + +// expected-error@+2 {{resource type 'RWByteAddressBuffer' cannot be used as a parameter of a noinline function}} +// expected-note@+1 {{attribute is here}} +__attribute__((noinline)) void no_prior_use(RWByteAddressBuffer A) {} diff --git a/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl b/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl index b65deeda9a4ff..0dc09e2a3c272 100644 --- a/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl +++ b/clang/test/SemaHLSL/Resources/unbounded_resource_arrays.hlsl @@ -1,21 +1,29 @@ -// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -finclude-default-header --o - %s -verify - -// unbounded resource array at a global scope -RWBuffer unbounded_array[]; // no_error - -// expected-error@+1 {{incomplete resource array in a function parameter}} -void foo(RWBuffer array_arg[]) {} - -RWBuffer A, B; - -[numthreads(4,1,1)] -void main() { - // expected-error@+1{{definition of variable with array type needs an explicit size or an initializer}} - RWBuffer res_local_array1[]; - - // expected-error@+1{{array initializer must be an initialzer list}} - RWBuffer res_local_array2[] = unbounded_array; - - // local incomplete resource array with initializer - RWBuffer res_local_array3[] = { A, B }; // no error -} +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -fsyntax-only -finclude-default-header %s -verify + +// unbounded resource array parameter whose resource type has not been used earlier +// expected-error@+1 {{incomplete resource array in a function parameter}} +void no_prior_use(RWByteAddressBuffer array_arg[]) {} + +// unbounded resource array at a global scope +RWBuffer unbounded_array[]; // no error + +// expected-error@+1 {{incomplete resource array in a function parameter}} +void foo(RWBuffer array_arg[]) {} + +// a non-resource incomplete-array parameter should not error +struct S; +void non_resource(S array_arg[]); // no error + +RWBuffer A, B; + +[numthreads(4,1,1)] +void main() { + // expected-error@+1{{definition of variable with array type needs an explicit size or an initializer}} + RWBuffer res_local_array1[]; + + // expected-error@+1{{array initializer must be an initializer list}} + RWBuffer res_local_array2[] = unbounded_array; + + // local incomplete resource array with initializer + RWBuffer res_local_array3[] = { A, B }; // no error +} From 9dabe383fd71aadb5588d1d5bb2eafe7b6fdf4f2 Mon Sep 17 00:00:00 2001 From: Chennes Date: Fri, 10 Jul 2026 06:36:55 +0800 Subject: [PATCH 037/125] [mlir][xegpu] Fix crash on 0D vector in vector-to-xegpu transfer lowering (#205812) `transferPreconditions` accepted rank-0 vectors, which then reached `computeOffsets` and indexed an empty `SmallVector` (`broadcasted[0]`), asserting `idx < size()` and crashing. For example: ```mlir vector.transfer_write %arg0, %arg1[%1] : vector, memref<3xf32> ``` This is valid IR (the verifier accepts it; 0D vector transfers are part of the vector dialect spec), so the conversion pass should not crash on it. Bail out via `notifyMatchFailure` for 0D vectors in the shared `transferPreconditions`, so both `transfer_read` and `transfer_write` are left unconverted instead of crashing. This matches how the core vector lowering already treats 0D transfers as an unsupported corner case (see `mlir/lib/Dialect/Vector/Transforms/LowerVectorTransfer.cpp`). Regression tests are added for 0D `transfer_read` and `transfer_write`. Fixes #205281 --- .../VectorToXeGPU/VectorToXeGPU.cpp | 2 ++ .../VectorToXeGPU/transfer-read-to-xegpu.mlir | 20 ++++++++++++++++++- .../transfer-write-to-xegpu.mlir | 17 ++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp b/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp index 8dcc9771d8db4..dd7330e4ea950 100644 --- a/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp +++ b/mlir/lib/Conversion/VectorToXeGPU/VectorToXeGPU.cpp @@ -97,6 +97,8 @@ static LogicalResult transferPreconditions(PatternRewriter &rewriter, VectorType vecTy = xferOp.getVectorType(); unsigned vecRank = vecTy.getRank(); + if (vecRank == 0) + return rewriter.notifyMatchFailure(xferOp, "0D vectors are not supported"); if (xferOp.hasOutOfBoundsDim() && vecRank < 2) return rewriter.notifyMatchFailure( xferOp, "Boundary check is available only for block instructions."); diff --git a/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir b/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir index f64bcc27940ea..6439e3a41e084 100644 --- a/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir +++ b/mlir/test/Conversion/VectorToXeGPU/transfer-read-to-xegpu.mlir @@ -679,4 +679,22 @@ gpu.func @load_0D_memref_unsupported(%source: memref) -> vector { // CHECK-LABEL: @load_0D_memref_unsupported // CHECK: vector.transfer_read -} \ No newline at end of file +} + +// ----- +gpu.module @xevm_module { +gpu.func @load_0D_vector_unsupported(%source: memref<3xf32>, + %offset: index) -> vector { + %c0 = arith.constant 0.0 : f32 + %0 = vector.transfer_read %source[%offset], %c0 + : memref<3xf32>, vector + gpu.return %0 : vector +} + +// LOAD-ND-LABEL: @load_0D_vector_unsupported +// LOAD-ND: vector.transfer_read + +// LOAD-GATHER-LABEL: @load_0D_vector_unsupported +// LOAD-GATHER: vector.transfer_read + +} diff --git a/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir b/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir index a7cd3d7652d85..755b8a3abc4e0 100644 --- a/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir +++ b/mlir/test/Conversion/VectorToXeGPU/transfer-write-to-xegpu.mlir @@ -412,3 +412,20 @@ gpu.func @store_1D_vector_addrspace3_unsupported(%vec: vector<8xf32>, // STORE-SCATTER: vector.transfer_write } + +// ----- +gpu.module @xevm_module { +gpu.func @store_0D_vector_unsupported(%vec: vector, + %source: memref<3xf32>, %offset: index) { + vector.transfer_write %vec, %source[%offset] + : vector, memref<3xf32> + gpu.return +} + +// STORE-ND-LABEL: @store_0D_vector_unsupported +// STORE-ND: vector.transfer_write + +// STORE-SCATTER-LABEL: @store_0D_vector_unsupported +// STORE-SCATTER: vector.transfer_write + +} From 9cfa768e63f81d91de4c6ceb1a3e101399e2dd99 Mon Sep 17 00:00:00 2001 From: Kewen Meng Date: Thu, 9 Jul 2026 15:37:13 -0700 Subject: [PATCH 038/125] [Offload][CI][AMDGPU] Update build scripts for updated triple (#208568) As new triple is introduced https://github.com/llvm/llvm-project/pull/206480, updated the build scripts accordingly. --- offload/ci/openmp-offload-amdgpu-clang-flang.py | 4 ++-- offload/ci/openmp-offload-amdgpu-libc-runtime.py | 8 ++++---- offload/ci/openmp-offload-amdgpu-runtime.py | 4 ++-- offload/cmake/caches/AMDGPUBot.cmake | 4 ++-- offload/cmake/caches/AMDGPULibcBot.cmake | 8 ++++---- offload/cmake/caches/FlangOffload.cmake | 10 +++++----- offload/cmake/caches/Offload.cmake | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/offload/ci/openmp-offload-amdgpu-clang-flang.py b/offload/ci/openmp-offload-amdgpu-clang-flang.py index ea31c5e87b1ff..c05663a783379 100755 --- a/offload/ci/openmp-offload-amdgpu-clang-flang.py +++ b/offload/ci/openmp-offload-amdgpu-clang-flang.py @@ -34,8 +34,8 @@ "-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath", "-DCMAKE_CXX_STANDARD=17", "-DLIBOMPTARGET_PLUGINS_TO_BUILD=amdgpu;host", - "-DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", - f"-DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES={w.in_llvmsrc('compiler-rt')}/cmake/caches/AMDGPU.cmake\;{w.in_llvmsrc('libcxx')}/cmake/caches/AMDGPU.cmake CACHE STRING '')", + "-DRUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", + f"-DRUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES={w.in_llvmsrc('compiler-rt')}/cmake/caches/AMDGPU.cmake\;{w.in_llvmsrc('libcxx')}/cmake/caches/AMDGPU.cmake CACHE STRING '')", ] ) diff --git a/offload/ci/openmp-offload-amdgpu-libc-runtime.py b/offload/ci/openmp-offload-amdgpu-libc-runtime.py index e1c4571544ed1..7c2b30747bc73 100644 --- a/offload/ci/openmp-offload-amdgpu-libc-runtime.py +++ b/offload/ci/openmp-offload-amdgpu-libc-runtime.py @@ -55,16 +55,16 @@ ["check-lld"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir ) - with w.step("run check-libc-amdgcn-amd-amdhsa"): + with w.step("run check-libc-amdgpu-amd-amdhsa"): w.run_ninja( - ["check-libc-amdgcn-amd-amdhsa"], + ["check-libc-amdgpu-amd-amdhsa"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir, ) - with w.step("run check-compiler-rt-amdgcn-amd-amdhsa"): + with w.step("run check-compiler-rt-amdgpu-amd-amdhsa"): w.run_ninja( - ["check-compiler-rt-amdgcn-amd-amdhsa"], + ["check-compiler-rt-amdgpu-amd-amdhsa"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir, ) diff --git a/offload/ci/openmp-offload-amdgpu-runtime.py b/offload/ci/openmp-offload-amdgpu-runtime.py index e93f54f09ac48..895b03edfb7fd 100755 --- a/offload/ci/openmp-offload-amdgpu-runtime.py +++ b/offload/ci/openmp-offload-amdgpu-runtime.py @@ -36,8 +36,8 @@ "-DLLVM_TARGETS_TO_BUILD=X86;AMDGPU", "-DCMAKE_C_COMPILER_LAUNCHER=ccache", "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", - "-DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", - "-DLLVM_RUNTIME_TARGETS=default;amdgcn-amd-amdhsa", + "-DRUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", + "-DLLVM_RUNTIME_TARGETS=default;amdgpu-amd-amdhsa", "-DLLVM_ENABLE_PROJECTS=clang;lld;llvm", "-DLLVM_ENABLE_RUNTIMES=offload;compiler-rt;openmp", ] diff --git a/offload/cmake/caches/AMDGPUBot.cmake b/offload/cmake/caches/AMDGPUBot.cmake index 11b2bbb16b210..0b7d520dd8453 100644 --- a/offload/cmake/caches/AMDGPUBot.cmake +++ b/offload/cmake/caches/AMDGPUBot.cmake @@ -22,5 +22,5 @@ set(LIBOMPTEST_BUILD_UNITTESTS ON CACHE BOOL "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") set(CLANG_DEFAULT_RTLIB "compiler-rt" STRING "") -set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "openmp" CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "openmp" CACHE STRING "") diff --git a/offload/cmake/caches/AMDGPULibcBot.cmake b/offload/cmake/caches/AMDGPULibcBot.cmake index 2dfff5dff8cf9..a450387c66ed7 100644 --- a/offload/cmake/caches/AMDGPULibcBot.cmake +++ b/offload/cmake/caches/AMDGPULibcBot.cmake @@ -16,7 +16,7 @@ set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") set(CLANG_DEFAULT_RTLIB "compiler-rt" STRING "") -set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;openmp;libc;libcxxabi;libcxx" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_LIBC_GPU_TEST_JOBS 4 CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;openmp;libc;libcxxabi;libcxx" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_LIBC_GPU_TEST_JOBS 4 CACHE STRING "") diff --git a/offload/cmake/caches/FlangOffload.cmake b/offload/cmake/caches/FlangOffload.cmake index a439e69881e20..3482a8030a1a6 100644 --- a/offload/cmake/caches/FlangOffload.cmake +++ b/offload/cmake/caches/FlangOffload.cmake @@ -2,12 +2,12 @@ set(LLVM_ENABLE_PROJECTS "clang;flang;mlir;clang-tools-extra;lld" CACHE STRING " set(LLVM_ENABLE_RUNTIMES "compiler-rt;flang-rt;libunwind;libcxx;libcxxabi;openmp;offload" CACHE STRING "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/NVPTX.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/NVPTX.cmake" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") diff --git a/offload/cmake/caches/Offload.cmake b/offload/cmake/caches/Offload.cmake index 8fcd2bc66ff9e..07a25a6a01591 100644 --- a/offload/cmake/caches/Offload.cmake +++ b/offload/cmake/caches/Offload.cmake @@ -2,8 +2,8 @@ set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld" CACHE STRING "") set(LLVM_ENABLE_RUNTIMES "compiler-rt;libunwind;libcxx;libcxxabi;openmp;offload" CACHE STRING "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/NVPTX.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/NVPTX.cmake" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") -set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") +set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") From 80d57d10969b7d1cbf20a28470c200d875b89e55 Mon Sep 17 00:00:00 2001 From: Jon Roelofs Date: Thu, 9 Jul 2026 15:38:13 -0700 Subject: [PATCH 039/125] [Attributor] Add remarks when UB is optimized to unreachable (#207864) These often bite LTO users in surprising and hard-to-debug ways. Adding remarks to give at least a small bread-crumb as to 'why' we're optimizing out chunks of code. --- llvm/lib/Transforms/IPO/Attributor.cpp | 10 +- .../Transforms/IPO/AttributorAttributes.cpp | 98 ++++++++++++++++--- .../Attributor/undefined_behavior.ll | 54 ++++++++++ 3 files changed, 144 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 0c4cc5451e736..9001507b7c70f 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -3870,6 +3870,7 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache, SetVector &Functions, AnalysisGetter &AG, CallGraphUpdater &CGUpdater, + FunctionAnalysisManager &FAM, bool DeleteFns, bool IsModulePass) { if (Functions.empty()) return false; @@ -3886,6 +3887,11 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache, AttributorConfig AC(CGUpdater); AC.IsModulePass = IsModulePass; AC.DeleteFns = DeleteFns; + auto OREGetter = [&FAM](Function *F) -> OptimizationRemarkEmitter & { + return FAM.getResult(*F); + }; + AC.OREGetter = OREGetter; + AC.PassName = DEBUG_TYPE; /// Tracking callback for specialization of indirect calls. DenseMap>> @@ -4099,7 +4105,7 @@ PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) { CallGraphUpdater CGUpdater; BumpPtrAllocator Allocator; InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ nullptr); - if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, + if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM, /* DeleteFns */ true, /* IsModulePass */ true)) { // FIXME: Think about passes we will preserve and add them here. return PreservedAnalyses::none(); @@ -4127,7 +4133,7 @@ PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C, CGUpdater.initialize(CG, C, AM, UR); BumpPtrAllocator Allocator; InformationCache InfoCache(M, AG, Allocator, /* CGSCC */ &Functions); - if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, + if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater, FAM, /* DeleteFns */ false, /* IsModulePass */ false)) { // FIXME: Think about passes we will preserve and add them here. diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 4d59f7dd2c3ee..99d86781cc122 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SCCIterator.h" @@ -2947,6 +2948,25 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) : AAUndefinedBehavior(IRP, A) {} + struct UBInfo { + enum Kind { + NullPtrAccess, + UndefPtrAccess, + UndefBranchCondition, + UndefReturnValue, + NullReturnViolatesNonNull, + UndefCallArgument, + NullArgViolatesNonNull, + }; + + Kind K; + std::optional ArgNo; + + UBInfo(Kind K) : K(K), ArgNo(std::nullopt) {} + + UBInfo(Kind K, std::optional ArgNo) : K(K), ArgNo(ArgNo) {} + }; + /// See AbstractAttribute::updateImpl(...). // through a pointer (i.e. also branches etc.) ChangeStatus updateImpl(Attributor &A) override { @@ -2973,7 +2993,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Either we stopped and the appropriate action was taken, // or we got back a simplified value to continue. std::optional SimplifiedPtrOp = - stopOnUndefOrAssumed(A, PtrOp, &I); + stopOnUndefOrAssumed(A, PtrOp, &I, UBInfo::UndefPtrAccess); if (!SimplifiedPtrOp || !*SimplifiedPtrOp) return true; const Value *PtrOpVal = *SimplifiedPtrOp; @@ -2996,7 +3016,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) AssumedNoUBInsts.insert(&I); else - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo::NullPtrAccess); return true; }; @@ -3013,8 +3033,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Either we stopped and the appropriate action was taken, // or we got back a simplified value to continue. - std::optional SimplifiedCond = - stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); + std::optional SimplifiedCond = stopOnUndefOrAssumed( + A, BrInst->getCondition(), BrInst, UBInfo::UndefBranchCondition); if (!SimplifiedCond || !*SimplifiedCond) return true; AssumedNoUBInsts.insert(&I); @@ -3066,7 +3086,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (SimplifiedVal && !*SimplifiedVal) return true; if (!SimplifiedVal || isa(**SimplifiedVal)) { - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo(UBInfo::UndefCallArgument, idx)); continue; } if (!ArgVal->getType()->isPointerTy() || @@ -3076,7 +3096,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { AA::hasAssumedIRAttr( A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); if (IsKnownNonNull) - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, + UBInfo(UBInfo::NullArgViolatesNonNull, idx)); } return true; }; @@ -3085,8 +3106,8 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { auto &RI = cast(I); // Either we stopped and the appropriate action was taken, // or we got back a simplified return value to continue. - std::optional SimplifiedRetValue = - stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); + std::optional SimplifiedRetValue = stopOnUndefOrAssumed( + A, RI.getReturnValue(), &I, UBInfo::UndefReturnValue); if (!SimplifiedRetValue || !*SimplifiedRetValue) return true; @@ -3110,7 +3131,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, IsKnownNonNull); if (IsKnownNonNull) - KnownUBInsts.insert(&I); + KnownUBInsts.try_emplace(&I, UBInfo::NullReturnViolatesNonNull); } return true; @@ -3174,11 +3195,55 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { return false; } + /// Emit an optimization remark explaining why \p I is known to cause UB, + /// per \p Info, right before it is replaced with 'unreachable'. + static void emitUBRemark(Attributor &A, Instruction *I, const UBInfo &Info) { + auto Remark = [&](OptimizationRemark OR) { + switch (Info.K) { + case UBInfo::NullPtrAccess: + case UBInfo::UndefPtrAccess: { + return OR << "Memory access through a pointer known to be " + << ore::NV("Pointer", + getPointerOperand(I, /*AllowVolatile*/ true)) + << " is undefined behavior; replacing with 'unreachable'."; + } + case UBInfo::UndefBranchCondition: + return OR << "Branch condition known to be " + << ore::NV("Condition", cast(I)->getCondition()) + << " is undefined behavior; replacing with 'unreachable'."; + case UBInfo::UndefReturnValue: + case UBInfo::NullReturnViolatesNonNull: + return OR << "Value returned known to be " + << ore::NV("ReturnValue", + cast(I)->getReturnValue()) + << " is undefined behavior; replacing with 'unreachable'."; + case UBInfo::UndefCallArgument: + case UBInfo::NullArgViolatesNonNull: { + bool IsUndef = Info.K == UBInfo::UndefCallArgument; + CallBase &CB = *cast(I); + OR << "Argument " << ore::NV("ArgNo", *Info.ArgNo) + << " passed to parameter of "; + if (auto *Callee = dyn_cast_if_present(CB.getCalledOperand())) + OR << ore::NV("Callee", Callee); + else + OR << "the callee"; + return OR << " known to be " + << ore::NV("Argument", IsUndef ? "undef" : "null") + << " is undefined behavior; replacing with 'unreachable'."; + } + } + llvm_unreachable("Unknown UBInfo::Kind"); + }; + A.emitRemark(I, "UndefinedBehavior", Remark); + } + ChangeStatus manifest(Attributor &A) override { if (KnownUBInsts.empty()) return ChangeStatus::UNCHANGED; - for (Instruction *I : KnownUBInsts) + for (const auto &[I, Info] : KnownUBInsts) { + emitUBRemark(A, I, Info); A.changeToUnreachableAfterManifest(I); + } return ChangeStatus::CHANGED; } @@ -3211,8 +3276,9 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { /// Note however that instructions in this set may cause UB. protected: - /// A set of all live instructions _known_ to cause UB. - SmallPtrSet KnownUBInsts; + /// A map from all live instructions _known_ to cause UB to the reason why, + /// used to build actionable optimization remarks in manifest(). + MapVector KnownUBInsts; private: /// A set of all the (live) instructions that are assumed to _not_ cause UB. @@ -3221,14 +3287,14 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { // Should be called on updates in which if we're processing an instruction // \p I that depends on a value \p V, one of the following has to happen: // - If the value is assumed, then stop. - // - If the value is known but undef, then consider it UB. + // - If the value is known but undef, then consider it UB for \p K. // - Otherwise, do specific processing with the simplified value. // We return std::nullopt in the first 2 cases to signify that an appropriate // action was taken and the caller should stop. // Otherwise, we return the simplified value that the caller should // use for specific processing. std::optional stopOnUndefOrAssumed(Attributor &A, Value *V, - Instruction *I) { + Instruction *I, UBInfo::Kind K) { bool UsedAssumedInformation = false; std::optional SimplifiedV = A.getAssumedSimplified(IRPosition::value(*V), *this, @@ -3238,7 +3304,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { if (!SimplifiedV) { // If it is known (which we tested above) but it doesn't have a value, // then we can assume `undef` and hence the instruction is UB. - KnownUBInsts.insert(I); + KnownUBInsts.try_emplace(I, K); return std::nullopt; } if (!*SimplifiedV) @@ -3246,7 +3312,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { V = *SimplifiedV; } if (isa(V)) { - KnownUBInsts.insert(I); + KnownUBInsts.try_emplace(I, K); return std::nullopt; } return V; diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll index ab80e6cbd797c..871914d7987f4 100644 --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -pass-remarks=attributor -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=REMARKS,REMARKS-TUNIT --implicit-check-not=remark +; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -pass-remarks=attributor -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=REMARKS,REMARKS-CGSCC --implicit-check-not=remark target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -16,10 +18,22 @@ define void @load_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = load i32, ptr null ret void } +define void @load_undef_pointer() { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; CHECK-LABEL: define {{[^@]+}}@load_undef_pointer +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: unreachable +; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be undef is undefined behavior; replacing with 'unreachable'. + %a = load i32, ptr undef + ret void +} + define void @load_wholly_unreachable_volatile() { ; CHECK: Function Attrs: nofree norecurse nosync nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable_volatile @@ -37,6 +51,8 @@ define void @loads_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = load i32, ptr null %b = load i32, ptr null ret void @@ -53,6 +69,7 @@ define void @load_single_bb_unreachable(i1 %cond) { ; CHECK: e: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %b = load i32, ptr null @@ -93,6 +110,7 @@ define void @load_null_propagated() { ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] { ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = load i32, ptr %ptr ret void @@ -106,6 +124,7 @@ define void @store_wholly_unreachable() { ; CHECK-SAME: () #[[ATTR0]] { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. store i32 5, ptr null ret void } @@ -131,6 +150,7 @@ define void @store_single_bb_unreachable(i1 %cond) { ; CHECK: e: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: store i32 5, ptr null @@ -171,6 +191,7 @@ define void @store_null_propagated() { ; CGSCC-NEXT: [[PTR:%.*]] = call noalias align 4294967296 ptr @ret_null() #[[ATTR11:[0-9]+]] ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() store i32 5, ptr %ptr ret void @@ -189,6 +210,7 @@ define void @atomicrmw_wholly_unreachable() { ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = atomicrmw add ptr null, i32 1 acquire ret void } @@ -212,6 +234,7 @@ define void @atomicrmw_single_bb_unreachable(i1 %cond) { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %a = atomicrmw add ptr null, i32 1 acquire @@ -253,6 +276,7 @@ define void @atomicrmw_null_propagated() { ; CGSCC-NEXT: [[A:%.*]] = atomicrmw add ptr [[PTR]], i32 1 acquire, align 4 ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = atomicrmw add ptr %ptr, i32 1 acquire ret void @@ -271,6 +295,7 @@ define void @atomiccmpxchg_wholly_unreachable() { ; CGSCC-SAME: () #[[ATTR6]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic ret void } @@ -294,6 +319,7 @@ define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t, label %e t: %a = cmpxchg ptr null, i32 2, i32 3 acq_rel monotonic @@ -335,6 +361,7 @@ define void @atomiccmpxchg_null_propagated() { ; CGSCC-NEXT: [[A:%.*]] = cmpxchg ptr [[PTR]], i32 2, i32 3 acq_rel monotonic, align 4 ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Memory access through a pointer known to be call is undefined behavior; replacing with 'unreachable'. %ptr = call ptr @ret_null() %a = cmpxchg ptr %ptr, i32 2, i32 3 acq_rel monotonic ret void @@ -363,6 +390,7 @@ define i32 @cond_br_on_undef() { ; CGSCC: e: ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Branch condition known to be undef is undefined behavior; replacing with 'unreachable'. br i1 undef, label %t, label %e t: ret i32 1 @@ -387,6 +415,7 @@ define void @cond_br_on_undef2(i1 %cond) { ; CHECK: e1: ; CHECK-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Branch condition known to be undef is undefined behavior; replacing with 'unreachable'. br i1 %cond, label %t1, label %e1 t1: br i1 undef, label %t2, label %e2 @@ -427,6 +456,7 @@ define void @cond_br_on_undef_interproc() { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Branch condition known to be call is undefined behavior; replacing with 'unreachable'. %cond = call i1 @ret_undef() br i1 %cond, label %t, label %e t: @@ -473,6 +503,7 @@ define void @cond_br_on_undef_interproc2() { ; CGSCC: e: ; CGSCC-NEXT: ret void ; +; REMARKS-TUNIT: remark: {{.*}}: Branch condition known to be call is undefined behavior; replacing with 'unreachable'. %cond = call i1 @ret_undef2() br i1 %cond, label %t, label %e t: @@ -502,6 +533,7 @@ define i32 @cond_br_on_undef3() { ; CGSCC: e: ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Branch condition known to be icmp is undefined behavior; replacing with 'unreachable'. %cond = icmp ne i32 1, undef br i1 %cond, label %t, label %e t: @@ -556,6 +588,7 @@ define internal i32 @callee(i1 %C, ptr %A) { ; CGSCC: F: ; CGSCC-NEXT: ret i32 1 ; +; REMARKS: remark: {{.*}}: Memory access through a pointer known to be null is undefined behavior; replacing with 'unreachable'. entry: %A.0 = load i32, ptr null br i1 %C, label %T, label %F @@ -715,6 +748,7 @@ define void @arg_nonnull_violation1_1() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1 known to be null is undefined behavior; replacing with 'unreachable'. call void @arg_nonnull_1(ptr null) ret void } @@ -730,6 +764,7 @@ define void @arg_nonnull_violation1_2() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1_noundef_1 known to be null is undefined behavior; replacing with 'unreachable'. call void @arg_nonnull_1_noundef_1(ptr null) ret void } @@ -746,6 +781,7 @@ define void @arg_nonnull_violation2_1(i1 %c) { ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1 known to be null is undefined behavior; replacing with 'unreachable'. %mustnull = select i1 %c, ptr null, ptr null call void @arg_nonnull_1(ptr %mustnull) ret void @@ -762,6 +798,7 @@ define void @arg_nonnull_violation2_2(i1 %c) { ; CGSCC-SAME: (i1 [[C:%.*]]) #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_1_noundef_1 known to be null is undefined behavior; replacing with 'unreachable'. %mustnull = select i1 %c, ptr null, ptr null call void @arg_nonnull_1_noundef_1(ptr %mustnull) ret void @@ -797,6 +834,12 @@ define void @arg_nonnull_violation3_1(i1 %c) { ; CGSCC: ret: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12 known to be null is undefined behavior; replacing with 'unreachable'. %ptr = alloca i32 br i1 %c, label %t, label %f t: @@ -844,6 +887,12 @@ define void @arg_nonnull_violation3_2(i1 %c) { ; CGSCC: ret: ; CGSCC-NEXT: ret void ; +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 1 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of arg_nonnull_12_noundef_2 known to be null is undefined behavior; replacing with 'unreachable'. %ptr = alloca i32 br i1 %c, label %t, label %f t: @@ -907,6 +956,7 @@ define noundef ptr @returned_noundef(i32 %c) { ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Value returned known to be undef is undefined behavior; replacing with 'unreachable'. switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: @@ -934,6 +984,8 @@ define nonnull noundef ptr @returned_nonnnull_noundef(i32 %c) { ; CHECK: ondefault: ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Value returned known to be null is undefined behavior; replacing with 'unreachable'. +; REMARKS: remark: {{.*}}: Value returned known to be undef is undefined behavior; replacing with 'unreachable'. switch i32 %c, label %ondefault [ i32 0, label %onzero i32 1, label %onone ] onzero: @@ -971,6 +1023,7 @@ define void @callsite_noundef_2() { ; CHECK-LABEL: define {{[^@]+}}@callsite_noundef_2() { ; CHECK-NEXT: unreachable ; +; REMARKS: remark: {{.*}}: Argument 0 passed to parameter of callee_ptr_arg known to be undef is undefined behavior; replacing with 'unreachable'. call void @callee_ptr_arg(ptr noundef undef) ret void } @@ -995,6 +1048,7 @@ define i32 @violate_noundef_nonpointer() { ; CGSCC-SAME: () #[[ATTR3]] { ; CGSCC-NEXT: unreachable ; +; REMARKS-CGSCC: remark: {{.*}}: Argument 0 passed to parameter of argument_noundef1 known to be undef is undefined behavior; replacing with 'unreachable'. %ret = call i32 @argument_noundef1(i32 undef) ret i32 %ret } From 314576176481027a0cb40790c43b851886ab3c55 Mon Sep 17 00:00:00 2001 From: Zhen Wang Date: Thu, 9 Jul 2026 15:44:40 -0700 Subject: [PATCH 040/125] [flang][cuda] Fix atomicCAS to return the old value (#208558) atomicCAS returned cmpxchg's success flag instead of the old value, breaking spinlock idioms. Extract element 0 (bitcast back for floats). --- flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp | 10 +++++++--- flang/test/Lower/CUDA/cuda-device-proc.cuf | 8 ++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp b/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp index 61c5e8131216e..ca200ac2cd02a 100644 --- a/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/CUDAIntrinsicCall.cpp @@ -882,9 +882,13 @@ CUDAIntrinsicLibrary::genAtomicCas(mlir::Type resultType, .getResult(0); auto cmpxchg = mlir::LLVM::AtomicCmpXchgOp::create( builder, loc, address, arg1, arg2, successOrdering, failureOrdering); - mlir::Value boolResult = - mlir::LLVM::ExtractValueOp::create(builder, loc, cmpxchg, 1); - return builder.createConvert(loc, resultType, boolResult); + // atomicCAS returns the value originally stored at the address, which is the + // first element of the cmpxchg result, not the success flag. + mlir::Value oldValue = + mlir::LLVM::ExtractValueOp::create(builder, loc, cmpxchg, 0); + if (mlir::isa(resultType)) + return mlir::LLVM::BitcastOp::create(builder, loc, resultType, oldValue); + return builder.createConvert(loc, resultType, oldValue); } mlir::Value diff --git a/flang/test/Lower/CUDA/cuda-device-proc.cuf b/flang/test/Lower/CUDA/cuda-device-proc.cuf index f252461700eda..864d1b7169bb1 100644 --- a/flang/test/Lower/CUDA/cuda-device-proc.cuf +++ b/flang/test/Lower/CUDA/cuda-device-proc.cuf @@ -311,7 +311,8 @@ end subroutine ! CHECK: %[[BCAST2:.*]] = llvm.bitcast %{{.*}} : f64 to i64 ! CHECK: %[[CAST:.*]] = builtin.unrealized_conversion_cast %{{.*}}#0 : !fir.ref to !llvm.ptr ! CHECK: %[[ATOMIC:.*]] = llvm.cmpxchg %[[CAST]], %[[BCAST1]], %[[BCAST2]] acq_rel monotonic : !llvm.ptr, i64 -! CHECK: %[[RES:.*]] = llvm.extractvalue %[[ATOMIC]][1] : !llvm.struct<(i64, i1)> +! CHECK: %[[RES:.*]] = llvm.extractvalue %[[ATOMIC]][0] : !llvm.struct<(i64, i1)> +! CHECK: %{{.*}} = llvm.bitcast %[[RES]] : i64 to f64 attributes(global) subroutine __ldXXi4(b) integer, device :: b(*) @@ -499,10 +500,9 @@ end subroutine ! CHECK-LABEL: func.func @_QPtestatomiccasloop ! CHECK: %[[CMP_XCHG:.*]] = llvm.cmpxchg %15, %c0_i32, %c1_i32 acq_rel monotonic : !llvm.ptr, i32 -! CHECK: %[[CMP_XCHG_EV:.*]] = llvm.extractvalue %[[CMP_XCHG]][1] : !llvm.struct<(i32, i1)> -! CHECK: %[[CASTED_CMP_XCHG_EV:.*]] = fir.convert %[[CMP_XCHG_EV]] : (i1) -> i32 +! CHECK: %[[CMP_XCHG_EV:.*]] = llvm.extractvalue %[[CMP_XCHG]][0] : !llvm.struct<(i32, i1)> ! CHECK: %{{.*}} = arith.constant 1 : i32 -! CHECK: %19 = arith.cmpi eq, %[[CASTED_CMP_XCHG_EV]], %{{.*}} : i32 +! CHECK: %{{.*}} = arith.cmpi eq, %[[CMP_XCHG_EV]], %{{.*}} : i32 attributes(global) subroutine test_barrier_try_wait() integer :: istat From 3a3d2cbc194b09e1a8bbbe1d3abb09c268cb3236 Mon Sep 17 00:00:00 2001 From: Jianhui Li Date: Thu, 9 Jul 2026 16:06:19 -0700 Subject: [PATCH 041/125] [mlir][xegpu] Fix expandDim distribution for shape_cast layout inference (#205987) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The expanded dims of a shape_cast collapse are row-major (innermost is fastest-varying), so sg_layout/lane_layout must be distributed inner-to-outer rather than outer-to-inner, and jointly with the data component: distribute sg_data/lane_data first, then stride sg_layout/lane_layout over the per-dim leftover. Example — shape_cast [8,32,32] -> [256,32] (consumer lane_layout=[8,4], lane_data=[2,1], order=[0,1]), inferred source layout: before: inst_data=[8,2,4], lane_layout=[8,1,4], lane_data=[1,2,1], order=[1,0,2] # lanes on slow dim after: inst_data=[1,16,4], lane_layout=[1,8,4], lane_data=[1,2,1], order=[1,0,2] # lanes wrap to fast dim This also fixes wrap-around, e.g. [2,16]->[32] with sg_layout=[4], sg_data=[4] → sg_layout=[1,4], sg_data=[1,4]. assisted-by-claude Co-authored-by: Claude Opus 4.8 (1M context) --- mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp | 136 ++++++++---------- .../XeGPU/propagate-layout-inst-data.mlir | 65 ++++----- .../XeGPU/propagate-layout-subgroup.mlir | 19 ++- mlir/test/Dialect/XeGPU/propagate-layout.mlir | 2 +- 4 files changed, 103 insertions(+), 119 deletions(-) diff --git a/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp b/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp index f9c258aba5bc7..0951350e2fe82 100644 --- a/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp +++ b/mlir/lib/Dialect/XeGPU/IR/XeGPUDialect.cpp @@ -704,40 +704,23 @@ DistributeLayoutAttr LayoutAttr::collapseDims(SmallVector dimGroup) { // Derive a new layout by expanding a single dimension `dim` into multiple // adjacent dimensions whose extents are given by `targetShape`. // -// Distribution is always outer-to-inner to make sure larger contiguous -// chunks are given to each compute unit first. Concretely: sg_layout and -// lane_layout walk the new dims outer-to-inner so each compute unit owns a -// contiguous run after collapse; sg_data / lane_data / inst_data fill -// innermost-first so the per-unit data tile is contiguous in the -// fastest-varying expanded dim. The expanded dims are assumed to be in -// row-major (FCD-first) order, which is intrinsic to `vector.shape_cast`'s -// linear-order-preserving semantics. -// -// Distribution policy on the expanded src dims (replacing `dim`): -// - sg_layout / lane_layout: spread outer-to-inner; each dim takes -// min(remaining, targetShape[i]); leftover spills into the next inner -// dim. -// - sg_data: fill innermost-first, capped per dim by -// targetShape[i] / sgLayout[i] (the per-sg share of the extent), -// or targetShape[i] (if sg_data is replicated across all subgroups). -// - lane_data: fill innermost-first, capped per dim by -// (targetShape[i] / sgLayout[i]) / laneLayout[i] (the per-lane share of -// the per-sg extent). -// - inst_data: seeded from laneLayout[i] * laneData[i] per dim, then the -// remaining factor is distributed innermost-first (capped per dim by -// the per-sg extent). -// - order: the original dim index is replaced by the expanded dim indices -// in innermost-fastest order; entries past `dim` shift up by -// `targetShape.size() - 1`. +// The expanded dims are row-major (innermost is fastest-varying), so every +// field is spread innermost-first. For sg and lane levels the data component +// (sg_data / lane_data) is distributed first and the layout component +// (sg_layout / lane_layout) then strides over the per-dim leftover; this +// shared inner-first sweep is what makes "wrap-around" distributions correct. +// When the data component spans the full extent (replicated/broadcast across +// subgroups or lanes), the layout component is capped by the full extent +// instead of the leftover. order entries past `dim` shift up by +// `targetShape.size() - 1`. // // Examples (only the affected dim shown; assume rank-1 input): -// layout, expandDim(0, [8, 16, 32]) -// -> sg_layout=[8, 1, 1], sg_data=[1, 16, 32] -// layout, expandDim(0, [2, 8, 32]) -// -> sg_layout=[2, 8, 1], sg_data=[1, 1, 32] (sg_layout spills inward) -// layout, -// expandDim(0, [8, 16, 32]) -// -> inst_data=[8, 2, 2], lane_layout=[8, 2, 1], lane_data=[1, 1, 1] +// sg_layout=[8], sg_data=[512], expandDim(0, [8,16,32]) +// -> sg_layout=[8,1,1], sg_data=[1,16,32] +// sg_layout=[4], sg_data=[4], expandDim(0, [2,16]) +// -> sg_layout=[1,4], sg_data=[1,4] (wrap-around) +// inst_data=[32], lane_layout=[16], lane_data=[1], expandDim(0, [8,16,32]) +// -> inst_data=[1,1,32], lane_layout=[1,1,16], lane_data=[1,1,1] DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, ArrayRef targetShape) { SmallVector sgLayout = getEffectiveSgLayoutAsInt(); @@ -761,29 +744,22 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, int64_t origLaneDataDim = laneData.empty() ? 1 : laneData[dim]; int64_t origInstDataDim = instData.empty() ? 1 : instData[dim]; - // Spread `total` across the new dims (length expCount), capped per dim by - // `dimSizeCap[i]`. `outerToInner` selects iteration direction - // (true = i=0..n-1). - auto spread = [&](int64_t total, ArrayRef dimSizeCap, - bool outerToInner) -> SmallVector { + // Spread `total` across the new dims (length expCount), innermost-first, + // capped per dim by `dimSizeCap[i]`. + auto spread = [&](int64_t total, + ArrayRef dimSizeCap) -> SmallVector { SmallVector out(expCount, 1); int64_t remaining = total; - auto step = [&](int64_t i) { + for (int64_t i = expCount - 1; i >= 0; --i) { if (remaining == 1) - return; + break; int64_t take = std::min(remaining, dimSizeCap[i]); assert(take > 0 && "expandDim distribution must not be zero"); assert(remaining % take == 0 && "expandDims must divide evenly across dims"); out[i] = take; remaining /= take; - }; - if (outerToInner) - for (int64_t i = 0; i < expCount; ++i) - step(i); - else - for (int64_t i = expCount - 1; i >= 0; --i) - step(i); + } assert(remaining == 1 && "expandDims total must fit within target shape"); return out; }; @@ -803,60 +779,61 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, bool hasLaneData = !laneData.empty(); bool hasInstData = !instData.empty(); - // sg_layout / sg_data - SmallVector expSgLayout(expCount, 1); - if (hasSgLayout) { - expSgLayout = spread(origSgLayoutDim, targetShape, /*outerToInner=*/true); - splice(sgLayout, expSgLayout); - } + // sg_data first, then sg_layout into the per-dim leftover. When sg_data is + // replicated across subgroups it spans the full extent, so sg_layout is + // capped by targetShape itself instead of the leftover. bool sgDataReplicated = hasSgData && origSgDataDim == computeProduct(targetShape); + SmallVector expSgData(expCount, 1); if (hasSgData) { + expSgData = spread(origSgDataDim, targetShape); + splice(sgData, expSgData); + } + SmallVector expSgLayout(expCount, 1); + if (hasSgLayout) { SmallVector dimSizeCap(targetShape.begin(), targetShape.end()); - if (hasSgLayout && !sgDataReplicated) + if (hasSgData && !sgDataReplicated) for (int64_t i = 0; i < expCount; ++i) - dimSizeCap[i] /= expSgLayout[i]; - SmallVector expSgData = - spread(origSgDataDim, dimSizeCap, /*outerToInner=*/false); - splice(sgData, expSgData); + dimSizeCap[i] /= expSgData[i]; + expSgLayout = spread(origSgLayoutDim, dimSizeCap); + splice(sgLayout, expSgLayout); } - // Per-sg view used as the base for lane_layout / lane_data / inst_data: - // targetShape[i] / sg_layout[i] when sg_layout is present (and not - // replicated), else targetShape itself. + // Per-sg extent feeding lane_layout / lane_data / inst_data. SmallVector perSgShape(targetShape.begin(), targetShape.end()); if (hasSgLayout && !sgDataReplicated) for (int64_t i = 0; i < expCount; ++i) perSgShape[i] /= expSgLayout[i]; - // lane_layout / lane_data + // lane_data first, then lane_layout into the per-dim leftover. When lane_data + // is replicated across lanes it spans the full per-sg extent, so lane_layout + // is capped by perSgShape itself instead of the leftover. + bool laneDataReplicated = + hasLaneData && origLaneDataDim == computeProduct(perSgShape); SmallVector expLaneLayout(expCount, 1); SmallVector expLaneData(expCount, 1); + if (hasLaneData) + expLaneData = spread(origLaneDataDim, perSgShape); if (hasLaneLayout) { - expLaneLayout = spread(origLaneLayoutDim, perSgShape, - /*outerToInner=*/true); - splice(laneLayout, expLaneLayout); - } - if (hasLaneData) { SmallVector dimSizeCap(perSgShape.begin(), perSgShape.end()); - if (hasLaneLayout) + if (hasLaneData && !laneDataReplicated) for (int64_t i = 0; i < expCount; ++i) - dimSizeCap[i] /= expLaneLayout[i]; - expLaneData = spread(origLaneDataDim, dimSizeCap, /*outerToInner=*/false); - splice(laneData, expLaneData); + dimSizeCap[i] /= expLaneData[i]; + expLaneLayout = spread(origLaneLayoutDim, dimSizeCap); } + if (hasLaneData) + splice(laneData, expLaneData); + if (hasLaneLayout) + splice(laneLayout, expLaneLayout); - // inst_data: when lane info is present, the per-lane atom - // `laneLayout[i] * laneData[i]` is the minimum granularity each new dim must - // hold to keep the lane-level distribution unit aligned with inst_data; the - // remaining factor `inst_data / laneAtom` is then spread innermost-first - // (capped by `perSgShape[i] / atom[i]`) and multiplied back onto the atom. - // Without lane info, fall back to a plain innermost-first spread over - // perSgShape. + // inst_data: seed each dim from the per-lane atom + // `laneLayout[i]*laneData[i]`, spread the remaining factor over the leftover, + // then scale back by the atom. Without lane info, spread inst_data directly + // over the per-sg extent. if (hasInstData) { SmallVector expInstData; if (!hasLaneLayout || !hasLaneData) { - expInstData = spread(origInstDataDim, perSgShape, /*outerToInner=*/false); + expInstData = spread(origInstDataDim, perSgShape); } else { int64_t laneAtom = origLaneLayoutDim * origLaneDataDim; SmallVector atom(expCount, 1); @@ -865,8 +842,7 @@ DistributeLayoutAttr LayoutAttr::expandDim(int64_t dim, atom[i] = expLaneLayout[i] * expLaneData[i]; dimSizeCap[i] = perSgShape[i] / atom[i]; } - expInstData = spread(origInstDataDim / laneAtom, dimSizeCap, - /*outerToInner=*/false); + expInstData = spread(origInstDataDim / laneAtom, dimSizeCap); for (int64_t i = 0; i < expCount; ++i) expInstData[i] *= atom[i]; } diff --git a/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir b/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir index 515c59db72819..c72e917b6fafa 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout-inst-data.mlir @@ -242,7 +242,7 @@ gpu.module @test { // CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense : vector<256xi1> // CHECK: %[[STEP:.*]] = vector.step {layout_result_0 = #xegpu.layout} : vector<256xindex> // CHECK: %[[LOAD:.*]] = xegpu.load %arg0[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : memref<256xf16>, vector<256xindex>, vector<256xi1> -> vector<256xf16> -// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> +// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> // CHECK: %[[CAST_1:.*]] = vector.shape_cast %[[CAST_0]] {layout_result_0 = #xegpu.layout} : vector<2x4x32xf16> to vector<1x256xf16> // CHECK: %[[CAST_2:.*]] = vector.shape_cast %[[CAST_1]] {layout_result_0 = #xegpu.layout} : vector<1x256xf16> to vector<256xf16> // CHECK: xegpu.store %[[CAST_2]], %arg1[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> @@ -453,21 +453,11 @@ func.func @dpas_mx_f4e2m1(%arg0: memref<16x1024xf4E2M1FN>, %arg1: memref<1024x32 } // ----- -// shape_cast that collapses all src dims into a single innermost dst dim. -// Consumer carries inst_data + lane_layout=[..,subgroupSize] + lane_data=[..,1] -// (the canonical inst-level anchor for this code path). -// Distribution is always outer-to-inner to make sure larger contiguous chunks -// are given to each compute unit first. -// srcShape=[8, 16, 32], resShape=[4096], consumer inst_data=[32], -// lane_layout=[16], lane_data=[1] -// lane_layout outer-to-inner: dim0 take=min(16,8)=8 (rem=2); -// dim1 take=min(2,16)=2 (rem=1) -> [8, 2, 1]. -// lane_data innermost-first: total=1 -> [1, 1, 1]. -// inst_data: laneAtom=16, seed [8, 2, 1]; remaining=32/16=2 spreads -// innermost-first: dim2 cap=32/1=32, take=2 -> inst_data[2]=2 -> [8, 2, 2]. +// shape_cast collapse [8, 16, 32] -> [4096]: lane/inst factors fill the fast +// innermost dim first. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_innermost( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<8x16x32xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<8x16x32xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<8x16x32xf16> to vector<4096xf16> func.func @vector_shape_cast_collapse_innermost(%arg0: memref<4096xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<8x16x32xf16> @@ -480,19 +470,11 @@ func.func @vector_shape_cast_collapse_innermost(%arg0: memref<4096xf16>) { } // ----- -// shape_cast collapse where the outermost src dim is too small to absorb the -// full lane_layout, so it spills inward across multiple src dims. -// srcShape=[2, 8, 32], resShape=[512], consumer inst_data=[64], -// lane_layout=[16], lane_data=[2] -// lane_layout outer-to-inner: dim0 take=min(16,2)=2 (rem=8); -// dim1 take=min(8,8)=8 (rem=1) -> [2, 8, 1]. -// lane_data innermost-first: total=2; dim2 cap=32/1=32, take=2 -> [1, 1, 2]. -// inst_data: laneAtom=16*2=32, seed [2*1, 8*1, 1*2] = [2, 8, 2]; -// remaining=64/32=2 spreads innermost-first: dim2 cap=32/2=16, take=2 -// -> inst_data[2] *= 2 -> [2, 8, 4]. +// shape_cast collapse [2, 8, 32] -> [512]: the innermost src dim absorbs the +// full lane distribution, leaving the remaining inst_data factor for dim 1. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_lane_layout_spill_inward( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x8x32xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x8x32xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x8x32xf16> to vector<512xf16> func.func @vector_shape_cast_collapse_lane_layout_spill_inward(%arg0: memref<512xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<2x8x32xf16> @@ -505,20 +487,11 @@ func.func @vector_shape_cast_collapse_lane_layout_spill_inward(%arg0: memref<512 } // ----- -// shape_cast collapse with multiple non-trivial groups: every dst dim -// collapses >=2 src dims, exercising the general matchDimCollapse path. -// srcShape=[2, 4, 8, 16], resShape=[8, 128], consumer inst_data=[1, 16], -// lane_layout=[1, 16], lane_data=[1, 1] -// - dst[0]=8 collapses src[0, 1]: lane_layout=1, lane_data=1, inst_data=1 -// -> [1, 1, _, _] for all three. -// - dst[1]=128 collapses src[2, 3]: lane_layout outer-to-inner over [2, 3]: -// dim2 take=min(16, 8)=8 (rem=2); dim3 take=min(2, 16)=2 (rem=1) -// -> [_, _, 8, 2]; lane_data=1 -> [_, _, 1, 1]; inst_data laneAtom=16, -// seed [_, _, 8*1, 2*1] = [_, _, 8, 2]; remaining=16/16=1 -> done -// -> inst_data=[_, _, 8, 2]. +// shape_cast collapse [2, 4, 8, 16] -> [8, 128]: multiple non-trivial groups, +// exercising the general matchDimCollapse path. gpu.module @test { // CHECK-LABEL: func.func @vector_shape_cast_collapse_multi_groups( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x4x8x16xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x4x8x16xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x4x8x16xf16> to vector<8x128xf16> func.func @vector_shape_cast_collapse_multi_groups(%arg0: memref<8x128xf16>) { %cst_v = arith.constant dense<0.000000e+00> : vector<2x4x8x16xf16> @@ -529,6 +502,24 @@ func.func @vector_shape_cast_collapse_multi_groups(%arg0: memref<8x128xf16>) { } } +// ----- +// broadcast feeding a shape_cast collapse [8, 32, 32] -> [256, 32]: lanes and +// lane_data of the collapsed dim wrap around onto the fast innermost dim. +gpu.module @test { +// CHECK-LABEL: gpu.func @shape_cast_collapse_lane_layout( +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} {{.*}} : vector<8x1x32xf8E8M0FNU> +// CHECK: %[[BC:.*]] = vector.broadcast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<8x1x32xf8E8M0FNU> to vector<8x32x32xf8E8M0FNU> +// CHECK: %[[CAST:.*]] = vector.shape_cast %[[BC]] {layout_result_0 = #xegpu.layout} : vector<8x32x32xf8E8M0FNU> to vector<256x32xf8E8M0FNU> + gpu.func @shape_cast_collapse_lane_layout(%dst: memref<256x32xf8E8M0FNU>) kernel { + %cst = arith.constant dense<0.000000e+00> : vector<8x1x32xf8E8M0FNU> + %bc = vector.broadcast %cst : vector<8x1x32xf8E8M0FNU> to vector<8x32x32xf8E8M0FNU> + %sc = vector.shape_cast %bc : vector<8x32x32xf8E8M0FNU> to vector<256x32xf8E8M0FNU> + %tdesc = xegpu.create_nd_tdesc %dst : memref<256x32xf8E8M0FNU> -> !xegpu.tensor_desc<256x32xf8E8M0FNU> + xegpu.store_nd %sc, %tdesc[0, 0] <{layout = #xegpu.layout}> : vector<256x32xf8E8M0FNU>, !xegpu.tensor_desc<256x32xf8E8M0FNU> + gpu.return + } +} + // ----- // completeBlockStoreLaneLayoutFromInstData: user supplies only inst_data on a // store_nd; lane_layout / lane_data are completed from it (data sink, no diff --git a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir index 4c6353e45cfbe..000f6c1cc916d 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir @@ -579,7 +579,7 @@ gpu.module @test { // ----- gpu.module @test { // CHECK-LABEL: gpu.func @shape_cast_collapse_replicated( -// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<16x8x8xf16> +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<16x8x8xf16> // CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<16x8x8xf16> to vector<16x64xf16> gpu.func @shape_cast_collapse_replicated(%dst: memref<16x64xf16>) kernel { %cst = arith.constant dense<0.000000e+00> : vector<16x8x8xf16> @@ -590,6 +590,23 @@ gpu.module @test { } } +// ----- +// shape_cast collapse [2, 16] -> [32] with sg_layout=[4], sg_data=[4]: +// the 4 subgroups wrap around onto the fast innermost dim. +gpu.module @test { +// CHECK-LABEL: gpu.func @shape_cast_collapse_sg_wraparound( +// CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense<0.000000e+00> : vector<2x16xf16> +// CHECK: %[[CAST:.*]] = vector.shape_cast %[[CST]] {layout_result_0 = #xegpu.layout} : vector<2x16xf16> to vector<32xf16> + gpu.func @shape_cast_collapse_sg_wraparound(%dst: memref<32xf16>) kernel { + %cst = arith.constant dense<0.000000e+00> : vector<2x16xf16> + %0 = vector.shape_cast %cst : vector<2x16xf16> to vector<32xf16> + %mask = arith.constant dense : vector<32xi1> + %offsets = vector.step : vector<32xindex> + xegpu.store %0, %dst[%offsets], %mask <{layout = #xegpu.layout}> : vector<32xf16>, memref<32xf16>, vector<32xindex>, vector<32xi1> + gpu.return + } +} + // ----- gpu.module @test { // CHECK-LABEL: gpu.func @transpose_3d_order_remap( diff --git a/mlir/test/Dialect/XeGPU/propagate-layout.mlir b/mlir/test/Dialect/XeGPU/propagate-layout.mlir index 1a741ba21e128..1311a6a588dbf 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout.mlir @@ -808,7 +808,7 @@ gpu.module @test { // CHECK: %[[CST:.*]] = arith.constant {layout_result_0 = #xegpu.layout} dense : vector<256xi1> // CHECK: %[[STEP:.*]] = vector.step {layout_result_0 = #xegpu.layout} : vector<256xindex> // CHECK: %[[LOAD:.*]] = xegpu.load %arg0[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : memref<256xf16>, vector<256xindex>, vector<256xi1> -> vector<256xf16> -// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> +// CHECK: %[[CAST_0:.*]] = vector.shape_cast %[[LOAD]] {layout_result_0 = #xegpu.layout} : vector<256xf16> to vector<2x4x32xf16> // CHECK: %[[CAST_1:.*]] = vector.shape_cast %[[CAST_0]] {layout_result_0 = #xegpu.layout} : vector<2x4x32xf16> to vector<1x256xf16> // CHECK: %[[CAST_2:.*]] = vector.shape_cast %[[CAST_1]] {layout_result_0 = #xegpu.layout} : vector<1x256xf16> to vector<256xf16> // CHECK: xegpu.store %[[CAST_2]], %arg1[%[[STEP]]], %[[CST]] <{layout = #xegpu.layout}> : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> From e2bd9ce693120b716c7e29e01be78ae7860e6616 Mon Sep 17 00:00:00 2001 From: Kewen Meng Date: Thu, 9 Jul 2026 16:13:05 -0700 Subject: [PATCH 042/125] Revert "[Offload][CI][AMDGPU] Update build scripts for updated triple" (#208583) Reverts llvm/llvm-project#208568 It breaks bots. --- offload/ci/openmp-offload-amdgpu-clang-flang.py | 4 ++-- offload/ci/openmp-offload-amdgpu-libc-runtime.py | 8 ++++---- offload/ci/openmp-offload-amdgpu-runtime.py | 4 ++-- offload/cmake/caches/AMDGPUBot.cmake | 4 ++-- offload/cmake/caches/AMDGPULibcBot.cmake | 8 ++++---- offload/cmake/caches/FlangOffload.cmake | 10 +++++----- offload/cmake/caches/Offload.cmake | 6 +++--- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/offload/ci/openmp-offload-amdgpu-clang-flang.py b/offload/ci/openmp-offload-amdgpu-clang-flang.py index c05663a783379..ea31c5e87b1ff 100755 --- a/offload/ci/openmp-offload-amdgpu-clang-flang.py +++ b/offload/ci/openmp-offload-amdgpu-clang-flang.py @@ -34,8 +34,8 @@ "-DFLANG_RUNTIME_F128_MATH_LIB=libquadmath", "-DCMAKE_CXX_STANDARD=17", "-DLIBOMPTARGET_PLUGINS_TO_BUILD=amdgpu;host", - "-DRUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", - f"-DRUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES={w.in_llvmsrc('compiler-rt')}/cmake/caches/AMDGPU.cmake\;{w.in_llvmsrc('libcxx')}/cmake/caches/AMDGPU.cmake CACHE STRING '')", + "-DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", + f"-DRUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES={w.in_llvmsrc('compiler-rt')}/cmake/caches/AMDGPU.cmake\;{w.in_llvmsrc('libcxx')}/cmake/caches/AMDGPU.cmake CACHE STRING '')", ] ) diff --git a/offload/ci/openmp-offload-amdgpu-libc-runtime.py b/offload/ci/openmp-offload-amdgpu-libc-runtime.py index 7c2b30747bc73..e1c4571544ed1 100644 --- a/offload/ci/openmp-offload-amdgpu-libc-runtime.py +++ b/offload/ci/openmp-offload-amdgpu-libc-runtime.py @@ -55,16 +55,16 @@ ["check-lld"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir ) - with w.step("run check-libc-amdgpu-amd-amdhsa"): + with w.step("run check-libc-amdgcn-amd-amdhsa"): w.run_ninja( - ["check-libc-amdgpu-amd-amdhsa"], + ["check-libc-amdgcn-amd-amdhsa"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir, ) - with w.step("run check-compiler-rt-amdgpu-amd-amdhsa"): + with w.step("run check-compiler-rt-amdgcn-amd-amdhsa"): w.run_ninja( - ["check-compiler-rt-amdgpu-amd-amdhsa"], + ["check-compiler-rt-amdgcn-amd-amdhsa"], add_env={"HSA_ENABLE_SDMA": "0"}, builddir=llvmbuilddir, ) diff --git a/offload/ci/openmp-offload-amdgpu-runtime.py b/offload/ci/openmp-offload-amdgpu-runtime.py index 895b03edfb7fd..e93f54f09ac48 100755 --- a/offload/ci/openmp-offload-amdgpu-runtime.py +++ b/offload/ci/openmp-offload-amdgpu-runtime.py @@ -36,8 +36,8 @@ "-DLLVM_TARGETS_TO_BUILD=X86;AMDGPU", "-DCMAKE_C_COMPILER_LAUNCHER=ccache", "-DCMAKE_CXX_COMPILER_LAUNCHER=ccache", - "-DRUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", - "-DLLVM_RUNTIME_TARGETS=default;amdgpu-amd-amdhsa", + "-DRUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES=compiler-rt;openmp", + "-DLLVM_RUNTIME_TARGETS=default;amdgcn-amd-amdhsa", "-DLLVM_ENABLE_PROJECTS=clang;lld;llvm", "-DLLVM_ENABLE_RUNTIMES=offload;compiler-rt;openmp", ] diff --git a/offload/cmake/caches/AMDGPUBot.cmake b/offload/cmake/caches/AMDGPUBot.cmake index 0b7d520dd8453..11b2bbb16b210 100644 --- a/offload/cmake/caches/AMDGPUBot.cmake +++ b/offload/cmake/caches/AMDGPUBot.cmake @@ -22,5 +22,5 @@ set(LIBOMPTEST_BUILD_UNITTESTS ON CACHE BOOL "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") set(CLANG_DEFAULT_RTLIB "compiler-rt" STRING "") -set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "openmp" CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "openmp" CACHE STRING "") diff --git a/offload/cmake/caches/AMDGPULibcBot.cmake b/offload/cmake/caches/AMDGPULibcBot.cmake index a450387c66ed7..2dfff5dff8cf9 100644 --- a/offload/cmake/caches/AMDGPULibcBot.cmake +++ b/offload/cmake/caches/AMDGPULibcBot.cmake @@ -16,7 +16,7 @@ set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "") set(CLANG_DEFAULT_RTLIB "compiler-rt" STRING "") -set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;openmp;libc;libcxxabi;libcxx" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_LIBC_GPU_TEST_JOBS 4 CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;openmp;libc;libcxxabi;libcxx" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_LIBC_GPU_TEST_JOBS 4 CACHE STRING "") diff --git a/offload/cmake/caches/FlangOffload.cmake b/offload/cmake/caches/FlangOffload.cmake index 3482a8030a1a6..a439e69881e20 100644 --- a/offload/cmake/caches/FlangOffload.cmake +++ b/offload/cmake/caches/FlangOffload.cmake @@ -2,12 +2,12 @@ set(LLVM_ENABLE_PROJECTS "clang;flang;mlir;clang-tools-extra;lld" CACHE STRING " set(LLVM_ENABLE_RUNTIMES "compiler-rt;flang-rt;libunwind;libcxx;libcxxabi;openmp;offload" CACHE STRING "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/NVPTX.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/NVPTX.cmake" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi;flang-rt" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBC_PROVIDER llvm CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_FLANG_RT_LIBCXX_PROVIDER llvm CACHE STRING "") diff --git a/offload/cmake/caches/Offload.cmake b/offload/cmake/caches/Offload.cmake index 07a25a6a01591..8fcd2bc66ff9e 100644 --- a/offload/cmake/caches/Offload.cmake +++ b/offload/cmake/caches/Offload.cmake @@ -2,8 +2,8 @@ set(LLVM_ENABLE_PROJECTS "clang;clang-tools-extra;lld" CACHE STRING "") set(LLVM_ENABLE_RUNTIMES "compiler-rt;libunwind;libcxx;libcxxabi;openmp;offload" CACHE STRING "") set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") -set(LLVM_RUNTIME_TARGETS default;amdgpu-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") +set(LLVM_RUNTIME_TARGETS default;amdgcn-amd-amdhsa;nvptx64-nvidia-cuda CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/NVPTX.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/NVPTX.cmake" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_CACHE_FILES "${CMAKE_SOURCE_DIR}/../compiler-rt/cmake/caches/AMDGPU.cmake;${CMAKE_SOURCE_DIR}/../libcxx/cmake/caches/AMDGPU.cmake" CACHE STRING "") set(RUNTIMES_nvptx64-nvidia-cuda_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") -set(RUNTIMES_amdgpu-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") +set(RUNTIMES_amdgcn-amd-amdhsa_LLVM_ENABLE_RUNTIMES "compiler-rt;libc;openmp;libcxx;libcxxabi" CACHE STRING "") From 2c04b3317301e09403b05ac88c5d69d4bc7fe80f Mon Sep 17 00:00:00 2001 From: Anshul Nigham Date: Thu, 9 Jul 2026 16:15:03 -0700 Subject: [PATCH 043/125] [Docs] Migrate LLVM docs to furo (#184440) Implements the proposal at https://discourse.llvm.org/t/rfc-update-llvm-docs-to-furo-theme/90053 Furo output at https://nigham.github.io/llvm_docs_furo/LangRef.html - Switched theme to Furo - Removed `:content` directives from RSTs, since Furo always has a TOC on the side. Credits for various pieces of feedback and improvements: @Pierre-vh @aengelke @slinder1 @jhuber6 @fmayer @llvm/infrastructure-area-team @petrhosek @rnk @boomanaiden154 (see discussions in the RFC) --- llvm/docs/AArch64SME.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX10.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX1011.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX1013.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX1030.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX11.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX12.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX7.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX8.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX9.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX900.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX904.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX906.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX908.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX90a.rst | 3 - llvm/docs/AMDGPU/AMDGPUAsmGFX940.rst | 3 - ...ionDescriptionOnTheDwarfExpressionStack.md | 6 +- ...arfExtensionsForHeterogeneousDebugging.rst | 3 - llvm/docs/AMDGPUInstructionNotation.rst | 3 - llvm/docs/AMDGPUInstructionSyntax.rst | 3 - llvm/docs/AMDGPUModifierSyntax.rst | 3 - llvm/docs/AMDGPUOperandSyntax.rst | 3 - llvm/docs/AMDGPUUsage.rst | 3 - llvm/docs/AddingConstrainedIntrinsics.rst | 3 - llvm/docs/AdvancedBuilds.md | 4 -- llvm/docs/AliasAnalysis.md | 4 -- llvm/docs/Atomics.md | 4 -- llvm/docs/BigEndianNEON.rst | 3 - llvm/docs/BitCodeFormat.md | 3 - llvm/docs/BlockFrequencyTerminology.rst | 3 - llvm/docs/BranchWeightMetadata.rst | 3 - llvm/docs/BugLifeCycle.rst | 5 -- llvm/docs/BuildingADistribution.md | 4 -- llvm/docs/CFIVerify.md | 4 -- llvm/docs/CMakePrimer.rst | 3 - llvm/docs/CodeGenerator.md | 4 -- llvm/docs/CodingStandards.md | 4 -- .../CommandGuide/llvm-debuginfo-analyzer.rst | 3 - llvm/docs/CommandGuide/llvm-pdbutil.rst | 3 - llvm/docs/CommandLine.md | 4 +- llvm/docs/CompileCudaWithLLVM.rst | 3 - llvm/docs/CompilerWriterInfo.md | 4 +- llvm/docs/ConvergenceAndUniformity.rst | 3 - llvm/docs/ConvergentOperations.rst | 4 -- llvm/docs/Coroutines.md | 5 -- llvm/docs/CoverageMappingFormat.md | 4 -- llvm/docs/CycleTerminology.md | 4 -- llvm/docs/DTLTO.md | 5 -- llvm/docs/DependenceGraphs/index.rst | 3 - llvm/docs/DeveloperPolicy.md | 4 -- llvm/docs/DirectX/DXContainer.rst | 3 - llvm/docs/DirectX/DXILArchitecture.rst | 3 - llvm/docs/DirectX/DXILOpTableGenDesign.rst | 3 - llvm/docs/DirectX/DXILResources.rst | 3 - llvm/docs/DirectX/RootSignatures.rst | 3 - llvm/docs/DirectXUsage.rst | 3 - llvm/docs/ExceptionHandling.md | 4 -- llvm/docs/Extensions.md | 4 +- llvm/docs/FAQ.md | 4 +- llvm/docs/FatLTO.rst | 4 -- llvm/docs/FaultMaps.rst | 4 -- llvm/docs/FuzzingLLVM.rst | 4 -- llvm/docs/GarbageCollection.md | 4 -- llvm/docs/GetElementPtr.rst | 3 - llvm/docs/GettingStarted.md | 4 -- llvm/docs/GettingStartedVS.md | 4 +- llvm/docs/GitHub.md | 4 -- llvm/docs/GlobalISel/GMIR.rst | 3 - llvm/docs/GlobalISel/GenericOpcode.rst | 3 - llvm/docs/GlobalISel/IRTranslator.rst | 3 - llvm/docs/GlobalISel/MIRPatterns.rst | 4 -- llvm/docs/GlobalISel/index.rst | 4 -- llvm/docs/GwpAsan.rst | 4 -- llvm/docs/HowToReleaseLLVM.rst | 3 - llvm/docs/HowToSetUpLLVMStyleRTTI.rst | 2 - llvm/docs/HowToUpdateDebugInfo.rst | 3 - llvm/docs/HowToUseAttributes.rst | 3 - llvm/docs/HowToUseInstrMappings.rst | 3 - llvm/docs/InstCombineContributorGuide.md | 4 -- llvm/docs/InstrProfileFormat.md | 4 +- llvm/docs/JITLink.rst | 3 - llvm/docs/KernelInfo.rst | 3 - llvm/docs/LFI.rst | 3 - llvm/docs/LangRef.md | 9 ++- llvm/docs/LibFuzzer.md | 20 ++---- llvm/docs/LoopTerminology.md | 4 -- llvm/docs/MIRLangRef.md | 4 +- llvm/docs/MLGO.rst | 2 - llvm/docs/MarkedUpDisassembly.rst | 3 - llvm/docs/MemTagSanitizer.rst | 3 - .../docs/MemoryModelRelaxationAnnotations.rst | 3 - llvm/docs/MemorySSA.md | 4 +- llvm/docs/MergeFunctions.md | 4 -- llvm/docs/MisExpect.rst | 2 - llvm/docs/MyFirstTypoFix.md | 4 -- llvm/docs/NVPTXUsage.rst | 5 -- llvm/docs/NewPassManager.md | 4 +- llvm/docs/ORCv2.rst | 3 - llvm/docs/OptBisect.rst | 4 -- llvm/docs/PCSectionsMetadata.rst | 3 - llvm/docs/PDB/CodeViewSymbols.rst | 3 - llvm/docs/PDB/CodeViewTypes.rst | 3 - llvm/docs/PDB/DbiStream.rst | 3 - llvm/docs/PDB/HashTable.rst | 3 - llvm/docs/PDB/ModiStream.rst | 3 - llvm/docs/PDB/MsfFile.rst | 3 - llvm/docs/PDB/PdbStream.rst | 3 - llvm/docs/PDB/TpiStream.rst | 3 - llvm/docs/PDB/index.rst | 3 - llvm/docs/Passes.md | 4 -- llvm/docs/Projects.rst | 3 - llvm/docs/Proposals/GitHubMove.rst | 4 -- llvm/docs/Proposals/TestSuite.rst | 4 -- llvm/docs/Proposals/VariableNames.rst | 3 - llvm/docs/Proposals/VectorPredication.rst | 4 -- llvm/docs/RFCProcess.md | 5 -- llvm/docs/RISCV/RISCVVectorExtension.rst | 3 - llvm/docs/RISCVUsage.rst | 3 - llvm/docs/ReleaseNotes.md | 3 +- llvm/docs/ReleaseProcess.rst | 16 ----- llvm/docs/Remarks.rst | 3 - llvm/docs/SPIRVUsage.rst | 3 - llvm/docs/SandboxVectorizer.md | 4 +- llvm/docs/ScudoHardenedAllocator.rst | 4 -- llvm/docs/SegmentedStacks.rst | 3 - llvm/docs/SphinxQuickstartTemplate.md | 4 +- llvm/docs/StackMaps.rst | 4 -- llvm/docs/Statepoints.rst | 4 -- llvm/docs/SymbolizerMarkupFormat.rst | 3 - llvm/docs/TableGen/BackEnds.rst | 3 - llvm/docs/TableGen/BackGuide.rst | 3 - llvm/docs/TableGen/ProgRef.rst | 3 - llvm/docs/Telemetry.rst | 3 - llvm/docs/TransformMetadata.rst | 3 - llvm/docs/UndefinedBehavior.rst | 4 -- llvm/docs/VectorizationPlan.rst | 3 - llvm/docs/Vectorizers.md | 4 -- llvm/docs/XRay.rst | 4 -- llvm/docs/XRayExample.rst | 3 - llvm/docs/XRayFDRFormat.rst | 4 -- llvm/docs/YamlIO.rst | 3 - llvm/docs/_static/LLVMWyvernSmall.png | Bin 0 -> 261036 bytes llvm/docs/_static/copybutton.css | 39 +++++++++++ llvm/docs/_static/copybutton.js | 56 ++++++++++++++++ llvm/docs/_static/custom.css | 62 ++++++++++++++++++ llvm/docs/conf.py | 31 ++++----- llvm/docs/tutorial/BuildingAJIT1.rst | 3 - llvm/docs/tutorial/BuildingAJIT2.rst | 3 - llvm/docs/tutorial/BuildingAJIT3.rst | 3 - llvm/docs/tutorial/BuildingAJIT4.rst | 3 - .../MyFirstLanguageFrontend/LangImpl01.rst | 3 - .../MyFirstLanguageFrontend/LangImpl02.rst | 3 - .../MyFirstLanguageFrontend/LangImpl03.rst | 3 - .../MyFirstLanguageFrontend/LangImpl04.rst | 3 - .../MyFirstLanguageFrontend/LangImpl05.rst | 3 - .../MyFirstLanguageFrontend/LangImpl06.rst | 3 - .../MyFirstLanguageFrontend/LangImpl07.rst | 3 - .../MyFirstLanguageFrontend/LangImpl08.rst | 3 - .../MyFirstLanguageFrontend/LangImpl09.rst | 3 - .../MyFirstLanguageFrontend/LangImpl10.rst | 3 - 160 files changed, 194 insertions(+), 553 deletions(-) create mode 100644 llvm/docs/_static/LLVMWyvernSmall.png create mode 100644 llvm/docs/_static/copybutton.css create mode 100644 llvm/docs/_static/copybutton.js create mode 100644 llvm/docs/_static/custom.css diff --git a/llvm/docs/AArch64SME.rst b/llvm/docs/AArch64SME.rst index d633dc2fbce2d..9fd4390103475 100644 --- a/llvm/docs/AArch64SME.rst +++ b/llvm/docs/AArch64SME.rst @@ -2,9 +2,6 @@ Support for AArch64 Scalable Matrix Extension in LLVM ***************************************************** -.. contents:: - :local: - 1. Introduction =============== diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX10.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX10.rst index f223f6c674a00..e052b7516d8c4 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX10.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX10.rst @@ -9,9 +9,6 @@ Syntax of GFX10 RDNA1 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX1011.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX1011.rst index 23790479c1800..83d7dc31dbd38 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX1011.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX1011.rst @@ -9,9 +9,6 @@ Syntax of gfx1011 and gfx1012 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX1013.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX1013.rst index 87dd73720abd6..e889bfb5d1874 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX1013.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX1013.rst @@ -9,9 +9,6 @@ Syntax of gfx1013 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX1030.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX1030.rst index 9c2fae26d60a7..6b3e3d73ba254 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX1030.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX1030.rst @@ -9,9 +9,6 @@ Syntax of GFX10 RDNA2 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX11.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX11.rst index 85e9c47a5c97d..15bedd662a102 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX11.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX11.rst @@ -9,9 +9,6 @@ Syntax of GFX11 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX12.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX12.rst index 5ed09d1e95f13..d60453a918a38 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX12.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX12.rst @@ -9,9 +9,6 @@ Syntax of GFX12 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX7.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX7.rst index 6c28480ac0223..3ead944afaa56 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX7.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX7.rst @@ -9,9 +9,6 @@ Syntax of GFX7 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX8.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX8.rst index 2f3dcfa36137b..d6d8ad4272234 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX8.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX8.rst @@ -9,9 +9,6 @@ Syntax of GFX8 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX9.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX9.rst index 13efe5711d8c8..720910434c82d 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX9.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX9.rst @@ -9,9 +9,6 @@ Syntax of Core GFX9 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX900.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX900.rst index b0ab856c44243..3f8e2fa56a311 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX900.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX900.rst @@ -9,9 +9,6 @@ Syntax of gfx900, gfx902, gfx909 and gfx90c Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX904.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX904.rst index 8bbb4c283203d..dff1e3a762363 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX904.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX904.rst @@ -9,9 +9,6 @@ Syntax of gfx904 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX906.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX906.rst index 92ca062ab975a..4da8692a30c1d 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX906.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX906.rst @@ -9,9 +9,6 @@ Syntax of gfx906 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX908.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX908.rst index 53fe42ed6eec1..7d53d3b92efa2 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX908.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX908.rst @@ -9,9 +9,6 @@ Syntax of gfx908 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX90a.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX90a.rst index a25dfd5826076..67cb8376b93c1 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX90a.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX90a.rst @@ -9,9 +9,6 @@ Syntax of gfx90a Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPU/AMDGPUAsmGFX940.rst b/llvm/docs/AMDGPU/AMDGPUAsmGFX940.rst index 7603bcc95383b..73af1e13e7c34 100644 --- a/llvm/docs/AMDGPU/AMDGPUAsmGFX940.rst +++ b/llvm/docs/AMDGPU/AMDGPUAsmGFX940.rst @@ -9,9 +9,6 @@ Syntax of gfx942 Instructions ==================================================================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md b/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md index e06c7ef80a09e..f6c56340dcc7f 100644 --- a/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md +++ b/llvm/docs/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack/AMDGPUDwarfExtensionAllowLocationDescriptionOnTheDwarfExpressionStack.md @@ -1,10 +1,6 @@ # Allow Location Descriptions on the DWARF Expression Stack -```{contents} ---- -local: ---- -``` + ## 1. Extension diff --git a/llvm/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.rst b/llvm/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.rst index 933f6dd72723c..2081f20fca42a 100644 --- a/llvm/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.rst +++ b/llvm/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.rst @@ -4,9 +4,6 @@ DWARF Extensions For Heterogeneous Debugging ******************************************** -.. contents:: - :local: - .. warning:: This document describes **provisional extensions** to DWARF Version 5 diff --git a/llvm/docs/AMDGPUInstructionNotation.rst b/llvm/docs/AMDGPUInstructionNotation.rst index 42e0c16235f4a..64c94cca76c10 100644 --- a/llvm/docs/AMDGPUInstructionNotation.rst +++ b/llvm/docs/AMDGPUInstructionNotation.rst @@ -2,9 +2,6 @@ AMDGPU Instructions Notation ============================ -.. contents:: - :local: - .. _amdgpu_syn_instruction_notation: Introduction diff --git a/llvm/docs/AMDGPUInstructionSyntax.rst b/llvm/docs/AMDGPUInstructionSyntax.rst index 38669a3c8d3e8..03a5b1ee6af16 100644 --- a/llvm/docs/AMDGPUInstructionSyntax.rst +++ b/llvm/docs/AMDGPUInstructionSyntax.rst @@ -2,9 +2,6 @@ AMDGPU Instruction Syntax ========================= -.. contents:: - :local: - .. _amdgpu_syn_instructions: Instructions diff --git a/llvm/docs/AMDGPUModifierSyntax.rst b/llvm/docs/AMDGPUModifierSyntax.rst index 8404a3e7b308d..b146ea771b003 100644 --- a/llvm/docs/AMDGPUModifierSyntax.rst +++ b/llvm/docs/AMDGPUModifierSyntax.rst @@ -2,9 +2,6 @@ Syntax of AMDGPU Instruction Modifiers ====================================== -.. contents:: - :local: - Conventions =========== diff --git a/llvm/docs/AMDGPUOperandSyntax.rst b/llvm/docs/AMDGPUOperandSyntax.rst index 247a10dd222e4..3acd9430f891e 100644 --- a/llvm/docs/AMDGPUOperandSyntax.rst +++ b/llvm/docs/AMDGPUOperandSyntax.rst @@ -2,9 +2,6 @@ Syntax of AMDGPU Instruction Operands ===================================== -.. contents:: - :local: - Conventions =========== diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index 9e401bc165b69..f9e92077ce9b8 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -4,9 +4,6 @@ User Guide for AMDGPU Backend ============================= -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/AddingConstrainedIntrinsics.rst b/llvm/docs/AddingConstrainedIntrinsics.rst index 4d1739ff11748..41494911e9aef 100644 --- a/llvm/docs/AddingConstrainedIntrinsics.rst +++ b/llvm/docs/AddingConstrainedIntrinsics.rst @@ -2,9 +2,6 @@ How To Add A Constrained Floating-Point Intrinsic ================================================== -.. contents:: - :local: - .. warning:: This is a work in progress. diff --git a/llvm/docs/AdvancedBuilds.md b/llvm/docs/AdvancedBuilds.md index 42847926dbbdc..3062a25a007a0 100644 --- a/llvm/docs/AdvancedBuilds.md +++ b/llvm/docs/AdvancedBuilds.md @@ -1,9 +1,5 @@ # Advanced Build Configurations -```{contents} -:local: -``` - ## Introduction [CMake](http://www.cmake.org/) is a cross-platform build-generator tool. CMake diff --git a/llvm/docs/AliasAnalysis.md b/llvm/docs/AliasAnalysis.md index a5da8817577c0..a87ba1a733e51 100644 --- a/llvm/docs/AliasAnalysis.md +++ b/llvm/docs/AliasAnalysis.md @@ -1,9 +1,5 @@ # LLVM Alias Analysis Infrastructure -```{contents} -:local: -``` - ## Introduction Alias Analysis (aka Pointer Analysis) is a class of techniques which attempt to diff --git a/llvm/docs/Atomics.md b/llvm/docs/Atomics.md index 2be51fbc20d4a..59ee8afe0f2a8 100644 --- a/llvm/docs/Atomics.md +++ b/llvm/docs/Atomics.md @@ -6,10 +6,6 @@ myst: # LLVM Atomic Instructions and Concurrency Guide -```{contents} -:local: -``` - ## Introduction LLVM supports instructions which are well-defined in the presence of threads and diff --git a/llvm/docs/BigEndianNEON.rst b/llvm/docs/BigEndianNEON.rst index a11f292a5a818..81a228a30bef8 100644 --- a/llvm/docs/BigEndianNEON.rst +++ b/llvm/docs/BigEndianNEON.rst @@ -2,9 +2,6 @@ Using ARM NEON instructions in big-endian mode ============================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/BitCodeFormat.md b/llvm/docs/BitCodeFormat.md index 5a64b9a2cb5f2..f0cd89ed3d7ff 100644 --- a/llvm/docs/BitCodeFormat.md +++ b/llvm/docs/BitCodeFormat.md @@ -1,9 +1,6 @@ # LLVM Bitcode File Format -```{contents} -:local: -``` ## Abstract diff --git a/llvm/docs/BlockFrequencyTerminology.rst b/llvm/docs/BlockFrequencyTerminology.rst index 84e144e922ef6..0b3795d8b0f63 100644 --- a/llvm/docs/BlockFrequencyTerminology.rst +++ b/llvm/docs/BlockFrequencyTerminology.rst @@ -2,9 +2,6 @@ LLVM Block Frequency Terminology ================================ -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/BranchWeightMetadata.rst b/llvm/docs/BranchWeightMetadata.rst index adcd17d694e82..d218992a44c68 100644 --- a/llvm/docs/BranchWeightMetadata.rst +++ b/llvm/docs/BranchWeightMetadata.rst @@ -2,9 +2,6 @@ LLVM Branch Weight Metadata =========================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/BugLifeCycle.rst b/llvm/docs/BugLifeCycle.rst index 1215af9e47e08..cf73ec036af0f 100644 --- a/llvm/docs/BugLifeCycle.rst +++ b/llvm/docs/BugLifeCycle.rst @@ -2,11 +2,6 @@ LLVM Bug Life Cycle =================== -.. contents:: - :local: - - - Introduction - Achieving consistency in how we deal with bug reports ==================================================================== diff --git a/llvm/docs/BuildingADistribution.md b/llvm/docs/BuildingADistribution.md index 680bcf0349a92..7aec94ba7d493 100644 --- a/llvm/docs/BuildingADistribution.md +++ b/llvm/docs/BuildingADistribution.md @@ -1,9 +1,5 @@ # Building a Distribution of LLVM -```{contents} -:local: -``` - ## Introduction This document is geared toward people who want to build and package LLVM and any diff --git a/llvm/docs/CFIVerify.md b/llvm/docs/CFIVerify.md index 5968bd7ed3fbe..3c97a7e6fa298 100644 --- a/llvm/docs/CFIVerify.md +++ b/llvm/docs/CFIVerify.md @@ -1,9 +1,5 @@ # Control Flow Verification Tool Design Document -```{contents} -:local: -``` - ## Objective This document provides an overview of an external tool to verify the protection diff --git a/llvm/docs/CMakePrimer.rst b/llvm/docs/CMakePrimer.rst index 5d244f443fbaf..90ab8d5aa46da 100644 --- a/llvm/docs/CMakePrimer.rst +++ b/llvm/docs/CMakePrimer.rst @@ -2,9 +2,6 @@ CMake Primer ============ -.. contents:: - :local: - .. warning:: Disclaimer: This documentation is written by LLVM project contributors `not` anyone affiliated with the CMake project. This document may contain diff --git a/llvm/docs/CodeGenerator.md b/llvm/docs/CodeGenerator.md index 0dc033d4e5cb6..0edd2af009be2 100644 --- a/llvm/docs/CodeGenerator.md +++ b/llvm/docs/CodeGenerator.md @@ -15,10 +15,6 @@ ``` -```{contents} -:local: -``` - ```{warning} This is a work in progress. ``` diff --git a/llvm/docs/CodingStandards.md b/llvm/docs/CodingStandards.md index 23e8aee3be938..7297b9096edf1 100644 --- a/llvm/docs/CodingStandards.md +++ b/llvm/docs/CodingStandards.md @@ -1,9 +1,5 @@ # LLVM Coding Standards -```{contents} -:local: -``` - ## Introduction This document describes coding standards that are used in the LLVM project. diff --git a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst index 221732775e74c..c7b5c12e3b98a 100644 --- a/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst +++ b/llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst @@ -3,9 +3,6 @@ llvm-debuginfo-analyzer - Print a logical representation of low-level debug info .. program:: llvm-debuginfo-analyzer -.. contents:: - :local: - SYNOPSIS -------- :program:`llvm-debuginfo-analyzer` [*options*] [*filename ...*] diff --git a/llvm/docs/CommandGuide/llvm-pdbutil.rst b/llvm/docs/CommandGuide/llvm-pdbutil.rst index 74e1444794dff..c2210ea4b7853 100644 --- a/llvm/docs/CommandGuide/llvm-pdbutil.rst +++ b/llvm/docs/CommandGuide/llvm-pdbutil.rst @@ -3,9 +3,6 @@ llvm-pdbutil - PDB File forensics and diagnostics .. program:: llvm-pdbutil -.. contents:: - :local: - Synopsis -------- diff --git a/llvm/docs/CommandLine.md b/llvm/docs/CommandLine.md index 883734e512c04..48604fa465466 100644 --- a/llvm/docs/CommandLine.md +++ b/llvm/docs/CommandLine.md @@ -1,8 +1,6 @@ # CommandLine 2.0 Library Manual -```{contents} -:local: -``` + ## Introduction diff --git a/llvm/docs/CompileCudaWithLLVM.rst b/llvm/docs/CompileCudaWithLLVM.rst index 7e0c99917795e..496493bd4e2ab 100644 --- a/llvm/docs/CompileCudaWithLLVM.rst +++ b/llvm/docs/CompileCudaWithLLVM.rst @@ -2,9 +2,6 @@ Compiling CUDA with clang ========================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/CompilerWriterInfo.md b/llvm/docs/CompilerWriterInfo.md index d7609a5a325de..f583fac2c7976 100644 --- a/llvm/docs/CompilerWriterInfo.md +++ b/llvm/docs/CompilerWriterInfo.md @@ -1,8 +1,6 @@ # Architecture & Platform Information for Compiler Writers -```{contents} -:local: -``` + ```{note} This document is a work-in-progress. Additions and clarifications are diff --git a/llvm/docs/ConvergenceAndUniformity.rst b/llvm/docs/ConvergenceAndUniformity.rst index 7ff9463d86cad..556a971da1e86 100644 --- a/llvm/docs/ConvergenceAndUniformity.rst +++ b/llvm/docs/ConvergenceAndUniformity.rst @@ -4,9 +4,6 @@ Convergence And Uniformity ========================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/ConvergentOperations.rst b/llvm/docs/ConvergentOperations.rst index cdd3e89aba1f4..20d8385ffc10e 100644 --- a/llvm/docs/ConvergentOperations.rst +++ b/llvm/docs/ConvergentOperations.rst @@ -2,10 +2,6 @@ Convergent Operation Semantics ============================== -.. contents:: - :local: - :depth: 4 - Overview ======== diff --git a/llvm/docs/Coroutines.md b/llvm/docs/Coroutines.md index eba5d458c09e8..012c5a661f605 100644 --- a/llvm/docs/Coroutines.md +++ b/llvm/docs/Coroutines.md @@ -1,10 +1,5 @@ # Coroutines in LLVM -```{contents} -:local: -:depth: 3 -``` - ```{warning} Compatibility across LLVM releases is not guaranteed. ``` diff --git a/llvm/docs/CoverageMappingFormat.md b/llvm/docs/CoverageMappingFormat.md index 4f72e1736de59..cbfe3dc47b8ef 100644 --- a/llvm/docs/CoverageMappingFormat.md +++ b/llvm/docs/CoverageMappingFormat.md @@ -1,9 +1,5 @@ # LLVM Code Coverage Mapping Format -```{contents} -:local: -``` - ## Introduction LLVM's code coverage mapping format is used to provide code coverage diff --git a/llvm/docs/CycleTerminology.md b/llvm/docs/CycleTerminology.md index 136d379268f86..9d94a3686280f 100644 --- a/llvm/docs/CycleTerminology.md +++ b/llvm/docs/CycleTerminology.md @@ -2,10 +2,6 @@ # LLVM Cycle Terminology -```{contents} -:local: -``` - (cycle-definition)= ## Cycles diff --git a/llvm/docs/DTLTO.md b/llvm/docs/DTLTO.md index 19fa0741d03f1..1805a0127db7e 100644 --- a/llvm/docs/DTLTO.md +++ b/llvm/docs/DTLTO.md @@ -1,10 +1,5 @@ # DTLTO -```{contents} -:depth: 2 -:local: -``` - ```{toctree} :maxdepth: 1 ``` diff --git a/llvm/docs/DependenceGraphs/index.rst b/llvm/docs/DependenceGraphs/index.rst index 7e8c73cad0008..60408ea687aae 100644 --- a/llvm/docs/DependenceGraphs/index.rst +++ b/llvm/docs/DependenceGraphs/index.rst @@ -2,9 +2,6 @@ Dependence Graphs in LLVM ========================= -.. contents:: - :local: - Introduction ============ Dependence graphs are useful tools in compilers for analyzing relationships diff --git a/llvm/docs/DeveloperPolicy.md b/llvm/docs/DeveloperPolicy.md index a447903167131..a2b9cc1e1e62d 100644 --- a/llvm/docs/DeveloperPolicy.md +++ b/llvm/docs/DeveloperPolicy.md @@ -1,10 +1,6 @@ (developer_policy)= # LLVM Developer Policy -```{contents} -:local: -``` - ## Introduction This document contains the LLVM Developer Policy which defines the project's diff --git a/llvm/docs/DirectX/DXContainer.rst b/llvm/docs/DirectX/DXContainer.rst index 4473f4ed8d002..2ef4919f908e4 100644 --- a/llvm/docs/DirectX/DXContainer.rst +++ b/llvm/docs/DirectX/DXContainer.rst @@ -2,9 +2,6 @@ DirectX Container ================= -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/DirectX/DXILArchitecture.rst b/llvm/docs/DirectX/DXILArchitecture.rst index bce7fdaa386ed..fd8f601f8710b 100644 --- a/llvm/docs/DirectX/DXILArchitecture.rst +++ b/llvm/docs/DirectX/DXILArchitecture.rst @@ -2,9 +2,6 @@ Architecture and Design of DXIL Support in LLVM =============================================== -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/DirectX/DXILOpTableGenDesign.rst b/llvm/docs/DirectX/DXILOpTableGenDesign.rst index 46106ee2a50f5..3352371b0d561 100644 --- a/llvm/docs/DirectX/DXILOpTableGenDesign.rst +++ b/llvm/docs/DirectX/DXILOpTableGenDesign.rst @@ -1,9 +1,6 @@ ============================================================== Specification of DXIL Operations using TableGen Representation ============================================================== -.. contents:: - :local: - .. toctree :hidden diff --git a/llvm/docs/DirectX/DXILResources.rst b/llvm/docs/DirectX/DXILResources.rst index 4471a248108cf..e617b1ce108a3 100644 --- a/llvm/docs/DirectX/DXILResources.rst +++ b/llvm/docs/DirectX/DXILResources.rst @@ -2,9 +2,6 @@ DXIL Resource Handling ====================== -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/DirectX/RootSignatures.rst b/llvm/docs/DirectX/RootSignatures.rst index e328b4a32cf12..72f743ae1a6c2 100644 --- a/llvm/docs/DirectX/RootSignatures.rst +++ b/llvm/docs/DirectX/RootSignatures.rst @@ -2,9 +2,6 @@ Root Signatures =============== -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/DirectXUsage.rst b/llvm/docs/DirectXUsage.rst index 78f27d89c1f8a..26f11a91964fc 100644 --- a/llvm/docs/DirectXUsage.rst +++ b/llvm/docs/DirectXUsage.rst @@ -7,9 +7,6 @@ User Guide for the DirectX Target It is not yet feature complete or ready to be used outside of experimental or demonstration contexts. -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/ExceptionHandling.md b/llvm/docs/ExceptionHandling.md index 9445f491f5238..7c34c1f934775 100644 --- a/llvm/docs/ExceptionHandling.md +++ b/llvm/docs/ExceptionHandling.md @@ -1,9 +1,5 @@ # Exception Handling in LLVM -```{contents} -:local: -``` - ## Introduction This document is the central repository for all information pertaining to diff --git a/llvm/docs/Extensions.md b/llvm/docs/Extensions.md index 2906b4c3f1b78..d6372275cedfe 100644 --- a/llvm/docs/Extensions.md +++ b/llvm/docs/Extensions.md @@ -1,8 +1,6 @@ # LLVM Extensions -```{contents} -:local: -``` + ```{toctree} :hidden: diff --git a/llvm/docs/FAQ.md b/llvm/docs/FAQ.md index 1b7d5e6a55923..ef0f18f103865 100644 --- a/llvm/docs/FAQ.md +++ b/llvm/docs/FAQ.md @@ -1,8 +1,6 @@ # Frequently Asked Questions (FAQ) -```{contents} -:local: -``` + ## License diff --git a/llvm/docs/FatLTO.rst b/llvm/docs/FatLTO.rst index c883513feb6ba..8bb13f560926b 100644 --- a/llvm/docs/FatLTO.rst +++ b/llvm/docs/FatLTO.rst @@ -1,10 +1,6 @@ =================== FatLTO =================== -.. contents:: - :local: - :depth: 2 - .. toctree:: :maxdepth: 1 diff --git a/llvm/docs/FaultMaps.rst b/llvm/docs/FaultMaps.rst index 5dc5e574fd2fa..46639b0730eea 100644 --- a/llvm/docs/FaultMaps.rst +++ b/llvm/docs/FaultMaps.rst @@ -2,10 +2,6 @@ FaultMaps and implicit checks ============================== -.. contents:: - :local: - :depth: 2 - Motivation ========== diff --git a/llvm/docs/FuzzingLLVM.rst b/llvm/docs/FuzzingLLVM.rst index 76eb4288a1f2c..931384b3f79b3 100644 --- a/llvm/docs/FuzzingLLVM.rst +++ b/llvm/docs/FuzzingLLVM.rst @@ -2,10 +2,6 @@ Fuzzing LLVM libraries and tools ================================ -.. contents:: - :local: - :depth: 2 - Introduction ============ diff --git a/llvm/docs/GarbageCollection.md b/llvm/docs/GarbageCollection.md index a94e566f8feb2..482aa4cf6bb12 100644 --- a/llvm/docs/GarbageCollection.md +++ b/llvm/docs/GarbageCollection.md @@ -1,9 +1,5 @@ # Garbage Collection with LLVM -```{contents} -:local: -``` - ## Abstract This document covers how to integrate LLVM into a compiler for a language which diff --git a/llvm/docs/GetElementPtr.rst b/llvm/docs/GetElementPtr.rst index 09389a0af751f..b16cfe0e205d7 100644 --- a/llvm/docs/GetElementPtr.rst +++ b/llvm/docs/GetElementPtr.rst @@ -2,9 +2,6 @@ The Often Misunderstood GEP Instruction ======================================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/GettingStarted.md b/llvm/docs/GettingStarted.md index ddc5fb73610e1..21940855faca2 100644 --- a/llvm/docs/GettingStarted.md +++ b/llvm/docs/GettingStarted.md @@ -1,9 +1,5 @@ # Getting Started with the LLVM System -```{contents} -:local: -``` - ## Overview Welcome to the LLVM project! diff --git a/llvm/docs/GettingStartedVS.md b/llvm/docs/GettingStartedVS.md index 232b5ab15fae2..4c1d065ca8523 100644 --- a/llvm/docs/GettingStartedVS.md +++ b/llvm/docs/GettingStartedVS.md @@ -1,8 +1,6 @@ # Getting Started with the LLVM System using Microsoft Visual Studio -```{contents} -:local: -``` + ## Overview diff --git a/llvm/docs/GitHub.md b/llvm/docs/GitHub.md index 6e343a66e5586..70a54d33e4979 100644 --- a/llvm/docs/GitHub.md +++ b/llvm/docs/GitHub.md @@ -2,10 +2,6 @@ # LLVM GitHub User Guide -```{contents} -:local: -``` - ## Introduction The LLVM Project uses [GitHub](https://github.com/) for diff --git a/llvm/docs/GlobalISel/GMIR.rst b/llvm/docs/GlobalISel/GMIR.rst index 494f6f24b8abb..e258e5cb7e779 100644 --- a/llvm/docs/GlobalISel/GMIR.rst +++ b/llvm/docs/GlobalISel/GMIR.rst @@ -3,9 +3,6 @@ Generic Machine IR ================== -.. contents:: - :local: - Generic MIR (gMIR) is an intermediate representation that shares the same data structures as :doc:`MachineIR (MIR) <../MIRLangRef>` but has more relaxed constraints. As the compilation pipeline proceeds, these constraints are diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst index df087adb6b43a..a65fc2c24a962 100644 --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -4,9 +4,6 @@ Generic Opcodes =============== -.. contents:: - :local: - .. note:: This documentation does not yet fully account for vectors. Many of the diff --git a/llvm/docs/GlobalISel/IRTranslator.rst b/llvm/docs/GlobalISel/IRTranslator.rst index f0a0611aaedac..fc6ca1f45f70b 100644 --- a/llvm/docs/GlobalISel/IRTranslator.rst +++ b/llvm/docs/GlobalISel/IRTranslator.rst @@ -3,9 +3,6 @@ IRTranslator ============ -.. contents:: - :local: - This pass translates the input LLVM-IR ``Function`` to a :doc:`GMIR` ``MachineFunction``. This is typically a direct translation but does occasionally get a bit more involved. For example: diff --git a/llvm/docs/GlobalISel/MIRPatterns.rst b/llvm/docs/GlobalISel/MIRPatterns.rst index 4e4ff1e897915..6d414175e0f12 100644 --- a/llvm/docs/GlobalISel/MIRPatterns.rst +++ b/llvm/docs/GlobalISel/MIRPatterns.rst @@ -5,10 +5,6 @@ MIR Patterns in TableGen ======================== -.. contents:: - :local: - - User's Guide ============ diff --git a/llvm/docs/GlobalISel/index.rst b/llvm/docs/GlobalISel/index.rst index 4951e09c257fd..aefdd805a4908 100644 --- a/llvm/docs/GlobalISel/index.rst +++ b/llvm/docs/GlobalISel/index.rst @@ -6,10 +6,6 @@ Global Instruction Selection This document is a work in progress. It reflects the current state of the implementation, as well as open design and implementation issues. -.. contents:: - :local: - :depth: 1 - .. toctree:: :hidden: diff --git a/llvm/docs/GwpAsan.rst b/llvm/docs/GwpAsan.rst index 937956fdabea7..2bb4078bf780b 100644 --- a/llvm/docs/GwpAsan.rst +++ b/llvm/docs/GwpAsan.rst @@ -2,10 +2,6 @@ GWP-ASan ======== -.. contents:: - :local: - :depth: 2 - Introduction ============ diff --git a/llvm/docs/HowToReleaseLLVM.rst b/llvm/docs/HowToReleaseLLVM.rst index 2524e1715ca18..e27ff7b492ddb 100644 --- a/llvm/docs/HowToReleaseLLVM.rst +++ b/llvm/docs/HowToReleaseLLVM.rst @@ -86,9 +86,6 @@ Release Process Summary Release Process =============== -.. contents:: - :local: - Release Administrative Tasks ---------------------------- diff --git a/llvm/docs/HowToSetUpLLVMStyleRTTI.rst b/llvm/docs/HowToSetUpLLVMStyleRTTI.rst index 7cfdaa07c5e79..b681bb768d99f 100644 --- a/llvm/docs/HowToSetUpLLVMStyleRTTI.rst +++ b/llvm/docs/HowToSetUpLLVMStyleRTTI.rst @@ -2,8 +2,6 @@ How to set up LLVM-style RTTI for your class hierarchy ====================================================== -.. contents:: - Background ========== diff --git a/llvm/docs/HowToUpdateDebugInfo.rst b/llvm/docs/HowToUpdateDebugInfo.rst index 428e3c1407a26..8d036eed2ac53 100644 --- a/llvm/docs/HowToUpdateDebugInfo.rst +++ b/llvm/docs/HowToUpdateDebugInfo.rst @@ -2,9 +2,6 @@ How to Update Debug Info: A Guide for LLVM Pass Authors ======================================================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/HowToUseAttributes.rst b/llvm/docs/HowToUseAttributes.rst index cc8a00ec5454b..b644543c572b0 100644 --- a/llvm/docs/HowToUseAttributes.rst +++ b/llvm/docs/HowToUseAttributes.rst @@ -2,9 +2,6 @@ How To Use Attributes ===================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/HowToUseInstrMappings.rst b/llvm/docs/HowToUseInstrMappings.rst index 17599da004ee1..ee140354042ab 100644 --- a/llvm/docs/HowToUseInstrMappings.rst +++ b/llvm/docs/HowToUseInstrMappings.rst @@ -2,9 +2,6 @@ How To Use Instruction Mappings =============================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/InstCombineContributorGuide.md b/llvm/docs/InstCombineContributorGuide.md index 1c432b9b7446c..d89293c7029d2 100644 --- a/llvm/docs/InstCombineContributorGuide.md +++ b/llvm/docs/InstCombineContributorGuide.md @@ -1,9 +1,5 @@ # InstCombine contributor guide -```{contents} -:depth: 4 -``` - This guide lays out a series of rules that contributions to InstCombine should follow. **Following these rules will results in much faster PR approvals.** diff --git a/llvm/docs/InstrProfileFormat.md b/llvm/docs/InstrProfileFormat.md index d491b2bcb8769..cbc228f042c3a 100644 --- a/llvm/docs/InstrProfileFormat.md +++ b/llvm/docs/InstrProfileFormat.md @@ -1,8 +1,6 @@ # Instrumentation Profile Format -```{contents} -:local: -``` + ## Overview diff --git a/llvm/docs/JITLink.rst b/llvm/docs/JITLink.rst index f3059b12984a8..e64cb3bd56225 100644 --- a/llvm/docs/JITLink.rst +++ b/llvm/docs/JITLink.rst @@ -2,9 +2,6 @@ JITLink and ORC's ObjectLinkingLayer ==================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/KernelInfo.rst b/llvm/docs/KernelInfo.rst index 9e397a977f298..89c734333b46b 100644 --- a/llvm/docs/KernelInfo.rst +++ b/llvm/docs/KernelInfo.rst @@ -2,9 +2,6 @@ KernelInfo ========== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/LFI.rst b/llvm/docs/LFI.rst index cf54e4e120026..c8213bf992f16 100644 --- a/llvm/docs/LFI.rst +++ b/llvm/docs/LFI.rst @@ -2,9 +2,6 @@ Lightweight Fault Isolation (LFI) in LLVM ========================================= -.. contents:: - :local: - Introduction ++++++++++++ diff --git a/llvm/docs/LangRef.md b/llvm/docs/LangRef.md index aff4297492445..7c03109f56652 100644 --- a/llvm/docs/LangRef.md +++ b/llvm/docs/LangRef.md @@ -1,9 +1,8 @@ -# LLVM Language Reference Manual +--- +tocdepth: 4 +--- -```{contents} -:local: -:depth: 3 -``` +# LLVM Language Reference Manual ## Abstract diff --git a/llvm/docs/LibFuzzer.md b/llvm/docs/LibFuzzer.md index 8fb098eeb9c9c..519eda8ff4b2a 100644 --- a/llvm/docs/LibFuzzer.md +++ b/llvm/docs/LibFuzzer.md @@ -1,8 +1,5 @@ # libFuzzer – a library for coverage-guided fuzz testing. -```{contents} -:local: -:depth: 1 -``` + ## Introduction @@ -32,10 +29,7 @@ LibFuzzer requires a matching version of Clang. ## Getting Started -```{contents} -:local: -:depth: 1 -``` + ### Fuzz Target @@ -420,10 +414,7 @@ about the mutation operation that produced the new input: ## Examples -```{contents} -:local: -:depth: 1 -``` + ### Toy example @@ -481,10 +472,7 @@ to detect [Heartbleed] in one second. ## Advanced features -```{contents} -:local: -:depth: 1 -``` + ### Dictionaries LibFuzzer supports user-supplied dictionaries with input language keywords diff --git a/llvm/docs/LoopTerminology.md b/llvm/docs/LoopTerminology.md index 23fa471ef016f..1e0381b9dd156 100644 --- a/llvm/docs/LoopTerminology.md +++ b/llvm/docs/LoopTerminology.md @@ -1,10 +1,6 @@ (loop-terminology)= # LLVM Loop Terminology (and Canonical Forms) -```{contents} -:local: -``` - ## Loop Definition Loops are an important concept for a code optimizer. In LLVM, detection diff --git a/llvm/docs/MIRLangRef.md b/llvm/docs/MIRLangRef.md index d5e837da9ecaf..a0f653f1e679e 100644 --- a/llvm/docs/MIRLangRef.md +++ b/llvm/docs/MIRLangRef.md @@ -1,8 +1,6 @@ # Machine IR (MIR) Format Reference Manual -```{contents} -:local: -``` + ```{warning} This is a work in progress. diff --git a/llvm/docs/MLGO.rst b/llvm/docs/MLGO.rst index de4d30e251d4b..f78478a1a3af7 100644 --- a/llvm/docs/MLGO.rst +++ b/llvm/docs/MLGO.rst @@ -24,8 +24,6 @@ This document is an outline of the tooling and APIs facilitating MLGO. of models during training. -.. contents:: - Corpus Tooling ============== diff --git a/llvm/docs/MarkedUpDisassembly.rst b/llvm/docs/MarkedUpDisassembly.rst index 05feee158e128..bb0328f0448a3 100644 --- a/llvm/docs/MarkedUpDisassembly.rst +++ b/llvm/docs/MarkedUpDisassembly.rst @@ -2,9 +2,6 @@ LLVM's Optional Rich Disassembly Output ======================================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/MemTagSanitizer.rst b/llvm/docs/MemTagSanitizer.rst index 8a0fffc0d3822..1cd2308a2f47c 100644 --- a/llvm/docs/MemTagSanitizer.rst +++ b/llvm/docs/MemTagSanitizer.rst @@ -2,9 +2,6 @@ MemTagSanitizer ================ -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/MemoryModelRelaxationAnnotations.rst b/llvm/docs/MemoryModelRelaxationAnnotations.rst index bcecca64f6891..61f83374a050f 100644 --- a/llvm/docs/MemoryModelRelaxationAnnotations.rst +++ b/llvm/docs/MemoryModelRelaxationAnnotations.rst @@ -2,9 +2,6 @@ Memory Model Relaxation Annotations =================================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/MemorySSA.md b/llvm/docs/MemorySSA.md index 0f0ea4607edad..b0c2d591906cd 100644 --- a/llvm/docs/MemorySSA.md +++ b/llvm/docs/MemorySSA.md @@ -1,8 +1,6 @@ # MemorySSA -```{contents} -:local: -``` + ## Introduction diff --git a/llvm/docs/MergeFunctions.md b/llvm/docs/MergeFunctions.md index 23f44de277943..40684e3c0dfc9 100644 --- a/llvm/docs/MergeFunctions.md +++ b/llvm/docs/MergeFunctions.md @@ -1,9 +1,5 @@ # MergeFunctions pass, how it works -```{contents} -:local: -``` - ## Introduction Sometimes code contains equal functions, or functions that do exactly the same diff --git a/llvm/docs/MisExpect.rst b/llvm/docs/MisExpect.rst index a9e6f8cc7006d..f143d70aeb9f6 100644 --- a/llvm/docs/MisExpect.rst +++ b/llvm/docs/MisExpect.rst @@ -1,8 +1,6 @@ =================== Misexpect =================== -.. contents:: - .. toctree:: :maxdepth: 1 diff --git a/llvm/docs/MyFirstTypoFix.md b/llvm/docs/MyFirstTypoFix.md index ca52154e3cfce..8fd99997d1014 100644 --- a/llvm/docs/MyFirstTypoFix.md +++ b/llvm/docs/MyFirstTypoFix.md @@ -1,9 +1,5 @@ # MyFirstTypoFix -```{contents} -:local: -``` - ## Introduction This tutorial will guide you through the process of making a change to diff --git a/llvm/docs/NVPTXUsage.rst b/llvm/docs/NVPTXUsage.rst index d6ca9154a1be9..aa9953499b8c6 100644 --- a/llvm/docs/NVPTXUsage.rst +++ b/llvm/docs/NVPTXUsage.rst @@ -2,11 +2,6 @@ User Guide for NVPTX Back-end ============================= -.. contents:: - :local: - :depth: 3 - - Introduction ============ diff --git a/llvm/docs/NewPassManager.md b/llvm/docs/NewPassManager.md index b712172dd881b..df933d190fe9d 100644 --- a/llvm/docs/NewPassManager.md +++ b/llvm/docs/NewPassManager.md @@ -1,8 +1,6 @@ # Using the New Pass Manager -```{contents} -:local: -``` + ## Overview diff --git a/llvm/docs/ORCv2.rst b/llvm/docs/ORCv2.rst index 333977a0aaa66..af633e1063761 100644 --- a/llvm/docs/ORCv2.rst +++ b/llvm/docs/ORCv2.rst @@ -2,9 +2,6 @@ ORC Design and Implementation =============================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/OptBisect.rst b/llvm/docs/OptBisect.rst index e3ba07834ec35..34ceeb7ceed8d 100644 --- a/llvm/docs/OptBisect.rst +++ b/llvm/docs/OptBisect.rst @@ -1,10 +1,6 @@ ==================================================== Using -opt-bisect-limit to debug optimization errors ==================================================== -.. contents:: - :local: - :depth: 1 - Introduction ============ diff --git a/llvm/docs/PCSectionsMetadata.rst b/llvm/docs/PCSectionsMetadata.rst index 4602ef0c60b32..d778ab269bbc4 100644 --- a/llvm/docs/PCSectionsMetadata.rst +++ b/llvm/docs/PCSectionsMetadata.rst @@ -2,9 +2,6 @@ LLVM PC Sections Metadata ========================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/PDB/CodeViewSymbols.rst b/llvm/docs/PDB/CodeViewSymbols.rst index b278b71c47f0b..7e1b4978d03dc 100644 --- a/llvm/docs/PDB/CodeViewSymbols.rst +++ b/llvm/docs/PDB/CodeViewSymbols.rst @@ -3,9 +3,6 @@ CodeView Symbol Records ===================================== -.. contents:: - :local: - .. _symbols_intro: Introduction diff --git a/llvm/docs/PDB/CodeViewTypes.rst b/llvm/docs/PDB/CodeViewTypes.rst index 996d8f93ba14e..05a85f39957f9 100644 --- a/llvm/docs/PDB/CodeViewTypes.rst +++ b/llvm/docs/PDB/CodeViewTypes.rst @@ -3,9 +3,6 @@ CodeView Type Records ===================================== -.. contents:: - :local: - .. _types_intro: Introduction diff --git a/llvm/docs/PDB/DbiStream.rst b/llvm/docs/PDB/DbiStream.rst index d8b3d665ed507..ff0d00ff9337c 100644 --- a/llvm/docs/PDB/DbiStream.rst +++ b/llvm/docs/PDB/DbiStream.rst @@ -2,9 +2,6 @@ The PDB DBI (Debug Info) Stream ===================================== -.. contents:: - :local: - .. _dbi_intro: Introduction diff --git a/llvm/docs/PDB/HashTable.rst b/llvm/docs/PDB/HashTable.rst index 7420510af5f8e..925b0bb6bf29c 100644 --- a/llvm/docs/PDB/HashTable.rst +++ b/llvm/docs/PDB/HashTable.rst @@ -1,9 +1,6 @@ The PDB Serialized Hash Table Format ==================================== -.. contents:: - :local: - .. _hash_intro: Introduction diff --git a/llvm/docs/PDB/ModiStream.rst b/llvm/docs/PDB/ModiStream.rst index 8905da5894576..1c0355cdbbb42 100644 --- a/llvm/docs/PDB/ModiStream.rst +++ b/llvm/docs/PDB/ModiStream.rst @@ -2,9 +2,6 @@ The Module Information Stream ===================================== -.. contents:: - :local: - .. _modi_stream_intro: Introduction diff --git a/llvm/docs/PDB/MsfFile.rst b/llvm/docs/PDB/MsfFile.rst index 4310494cf1bbf..5d1b7dbd52216 100644 --- a/llvm/docs/PDB/MsfFile.rst +++ b/llvm/docs/PDB/MsfFile.rst @@ -2,9 +2,6 @@ The MSF File Format ===================================== -.. contents:: - :local: - .. _msf_layout: File Layout diff --git a/llvm/docs/PDB/PdbStream.rst b/llvm/docs/PDB/PdbStream.rst index 417b421a45201..4cca4820889b4 100644 --- a/llvm/docs/PDB/PdbStream.rst +++ b/llvm/docs/PDB/PdbStream.rst @@ -2,9 +2,6 @@ The PDB Info Stream (aka the PDB Stream) ======================================== -.. contents:: - :local: - .. _pdb_stream_header: Stream Header diff --git a/llvm/docs/PDB/TpiStream.rst b/llvm/docs/PDB/TpiStream.rst index a6d6daad2abc0..6bfd92c2db8b9 100644 --- a/llvm/docs/PDB/TpiStream.rst +++ b/llvm/docs/PDB/TpiStream.rst @@ -2,9 +2,6 @@ The PDB TPI and IPI Streams ===================================== -.. contents:: - :local: - .. _tpi_intro: Introduction diff --git a/llvm/docs/PDB/index.rst b/llvm/docs/PDB/index.rst index 4bd6f18b37709..8d878767e98e0 100644 --- a/llvm/docs/PDB/index.rst +++ b/llvm/docs/PDB/index.rst @@ -2,9 +2,6 @@ The PDB File Format ===================================== -.. contents:: - :local: - .. _pdb_intro: Introduction diff --git a/llvm/docs/Passes.md b/llvm/docs/Passes.md index 36159ff0c5206..8a32ddd98b6a1 100644 --- a/llvm/docs/Passes.md +++ b/llvm/docs/Passes.md @@ -1,9 +1,5 @@ # LLVM's Analysis and Transform Passes -```{contents} -:local: -``` - ```{toctree} :hidden: diff --git a/llvm/docs/Projects.rst b/llvm/docs/Projects.rst index cbf8f5012b908..ce65436eaec8b 100644 --- a/llvm/docs/Projects.rst +++ b/llvm/docs/Projects.rst @@ -2,9 +2,6 @@ Creating an LLVM Project ======================== -.. contents:: - :local: - Overview ======== diff --git a/llvm/docs/Proposals/GitHubMove.rst b/llvm/docs/Proposals/GitHubMove.rst index dbb38ee985442..dcd0deb33f076 100644 --- a/llvm/docs/Proposals/GitHubMove.rst +++ b/llvm/docs/Proposals/GitHubMove.rst @@ -9,10 +9,6 @@ We are planning to complete the transition to GitHub by Oct 21, 2019. See the GitHub migration `status page `_ for the latest updates and instructions for how to migrate your workflows. -.. contents:: Table of Contents - :depth: 4 - :local: - Introduction ============ diff --git a/llvm/docs/Proposals/TestSuite.rst b/llvm/docs/Proposals/TestSuite.rst index 33bb890244ffb..f9a3e6e598b1f 100644 --- a/llvm/docs/Proposals/TestSuite.rst +++ b/llvm/docs/Proposals/TestSuite.rst @@ -2,10 +2,6 @@ Test-Suite Extensions ===================== -.. contents:: - :depth: 1 - :local: - Abstract ======== diff --git a/llvm/docs/Proposals/VariableNames.rst b/llvm/docs/Proposals/VariableNames.rst index 80a86f7da0ef6..3bf560f3dab8e 100644 --- a/llvm/docs/Proposals/VariableNames.rst +++ b/llvm/docs/Proposals/VariableNames.rst @@ -2,9 +2,6 @@ Variable Names Plan =================== -.. contents:: - :local: - This plan is *provisional*. It is not agreed upon. It is written with the intention of capturing the desires and concerns of the LLVM community, and forming them into a plan that can be agreed upon. diff --git a/llvm/docs/Proposals/VectorPredication.rst b/llvm/docs/Proposals/VectorPredication.rst index 4e93f4fea31ba..99bfc5521fd75 100644 --- a/llvm/docs/Proposals/VectorPredication.rst +++ b/llvm/docs/Proposals/VectorPredication.rst @@ -2,10 +2,6 @@ Vector Predication Roadmap ========================== -.. contents:: Table of Contents - :depth: 3 - :local: - Motivation ========== diff --git a/llvm/docs/RFCProcess.md b/llvm/docs/RFCProcess.md index e45c2782301dc..88a4509463cdf 100644 --- a/llvm/docs/RFCProcess.md +++ b/llvm/docs/RFCProcess.md @@ -1,10 +1,5 @@ # Request For Comment (RFC) process -```{contents} -:local: -:depth: 1 -``` - ## Introduction Substantive changes to LLVM projects need to be acceptable to the wider diff --git a/llvm/docs/RISCV/RISCVVectorExtension.rst b/llvm/docs/RISCV/RISCVVectorExtension.rst index e9d1c7b95d6d5..51c29254600b0 100644 --- a/llvm/docs/RISCV/RISCVVectorExtension.rst +++ b/llvm/docs/RISCV/RISCVVectorExtension.rst @@ -2,9 +2,6 @@ RISC-V Vector Extension ========================= -.. contents:: - :local: - The RISC-V target supports the 1.0 version of the `RISC-V Vector Extension (RVV) `_. This guide gives an overview of how it's modelled in LLVM IR and how the backend generates code for it. diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 7cfbd967eee77..644d3d75bbdfe 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -2,9 +2,6 @@ User Guide for RISC-V Target ============================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 4548be37e7f4c..3edc77b0a249e 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -6,8 +6,7 @@ ReleaseNotes.md and ReleaseNotesTemplate.txt. --> # LLVM {{env.config.release}} Release Notes -```{contents} -``` + ````{only} PreRelease ```{warning} These are in-progress notes for the upcoming LLVM {{env.config.release}} diff --git a/llvm/docs/ReleaseProcess.rst b/llvm/docs/ReleaseProcess.rst index 82f841f8d62c5..c944dbefc3dd0 100644 --- a/llvm/docs/ReleaseProcess.rst +++ b/llvm/docs/ReleaseProcess.rst @@ -2,10 +2,6 @@ How To Validate a New Release ============================= -.. contents:: - :local: - :depth: 1 - Introduction ============ @@ -111,9 +107,6 @@ TODO Test Suite ========== -.. contents:: - :local: - Follow the `LNT Quick Start Guide `__ link on how to set-up the test-suite @@ -150,9 +143,6 @@ fixed on a future date. Pre-Release Process =================== -.. contents:: - :local: - When the release process is announced on the mailing list, you should prepare for the testing, by applying the same testing you'll do on the release candidates, on the previous release. @@ -180,9 +170,6 @@ when reducing the error for bug report purposes). Release Process =============== -.. contents:: - :local: - When the Release Manager sends you the release candidate, download all sources, unzip on the same directory (there will be sym-links from the appropriate places to them), and run the release test as above. @@ -214,9 +201,6 @@ and that will be the official binary. Bug Reporting Process ===================== -.. contents:: - :local: - If you found regressions or failures when comparing a release candidate with the previous release, follow the rules below: diff --git a/llvm/docs/Remarks.rst b/llvm/docs/Remarks.rst index a22e8c30dfa30..ae215f2b51ec7 100644 --- a/llvm/docs/Remarks.rst +++ b/llvm/docs/Remarks.rst @@ -2,9 +2,6 @@ Remarks ======= -.. contents:: - :local: - Introduction to the LLVM remark diagnostics =========================================== diff --git a/llvm/docs/SPIRVUsage.rst b/llvm/docs/SPIRVUsage.rst index a820e2e6ff6e4..92738ac177e8f 100644 --- a/llvm/docs/SPIRVUsage.rst +++ b/llvm/docs/SPIRVUsage.rst @@ -2,9 +2,6 @@ User Guide for SPIR-V Target ============================= -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/SandboxVectorizer.md b/llvm/docs/SandboxVectorizer.md index e5068f7724ea9..9c4252ce809ee 100644 --- a/llvm/docs/SandboxVectorizer.md +++ b/llvm/docs/SandboxVectorizer.md @@ -1,8 +1,6 @@ # The Sandbox Vectorizer -```{contents} -:depth: 4 -``` + The Sandbox Vectorizer is a framework for building modular vectorization pipelines on top of [Sandbox IR](#SandboxIR) transactional IR, with a focus on ease of development and testing. The default pipeline currently implements a simple SLP-style bottom-up vectorization pipeline. diff --git a/llvm/docs/ScudoHardenedAllocator.rst b/llvm/docs/ScudoHardenedAllocator.rst index 328c883bbd5db..a840e4f3fc826 100644 --- a/llvm/docs/ScudoHardenedAllocator.rst +++ b/llvm/docs/ScudoHardenedAllocator.rst @@ -2,10 +2,6 @@ Scudo Hardened Allocator ======================== -.. contents:: - :local: - :depth: 2 - Introduction ============ diff --git a/llvm/docs/SegmentedStacks.rst b/llvm/docs/SegmentedStacks.rst index b1c588cb16367..59a7a36e05a0e 100644 --- a/llvm/docs/SegmentedStacks.rst +++ b/llvm/docs/SegmentedStacks.rst @@ -2,9 +2,6 @@ Segmented Stacks in LLVM ======================== -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/SphinxQuickstartTemplate.md b/llvm/docs/SphinxQuickstartTemplate.md index 9b17c332e807b..73ca4b40704e3 100644 --- a/llvm/docs/SphinxQuickstartTemplate.md +++ b/llvm/docs/SphinxQuickstartTemplate.md @@ -2,9 +2,7 @@ This article is intended to take someone in the state of “I want to write documentation and get it added to LLVM’s docs” and help them start writing documentation as fast as possible and with as little nonsense as possible. -```{contents} -:local: -``` + ## Overview diff --git a/llvm/docs/StackMaps.rst b/llvm/docs/StackMaps.rst index 56c82e2863c3b..befccc438e856 100644 --- a/llvm/docs/StackMaps.rst +++ b/llvm/docs/StackMaps.rst @@ -2,10 +2,6 @@ Stack maps and patch points in LLVM =================================== -.. contents:: - :local: - :depth: 2 - Definitions =========== diff --git a/llvm/docs/Statepoints.rst b/llvm/docs/Statepoints.rst index 27a46a43b5190..2c703b8f11782 100644 --- a/llvm/docs/Statepoints.rst +++ b/llvm/docs/Statepoints.rst @@ -2,10 +2,6 @@ Garbage Collection Safepoints in LLVM ===================================== -.. contents:: - :local: - :depth: 2 - Status ======= diff --git a/llvm/docs/SymbolizerMarkupFormat.rst b/llvm/docs/SymbolizerMarkupFormat.rst index 75ead442af6e0..a67c354a2f4b5 100644 --- a/llvm/docs/SymbolizerMarkupFormat.rst +++ b/llvm/docs/SymbolizerMarkupFormat.rst @@ -2,9 +2,6 @@ Symbolizer Markup Format ========================== -.. contents:: - :local: - Overview ======== diff --git a/llvm/docs/TableGen/BackEnds.rst b/llvm/docs/TableGen/BackEnds.rst index e89b1fa2abcb7..8a2a917c1ac79 100644 --- a/llvm/docs/TableGen/BackEnds.rst +++ b/llvm/docs/TableGen/BackEnds.rst @@ -2,9 +2,6 @@ TableGen BackEnds ================= -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/TableGen/BackGuide.rst b/llvm/docs/TableGen/BackGuide.rst index 7883d7c6f529c..046b0461baf83 100644 --- a/llvm/docs/TableGen/BackGuide.rst +++ b/llvm/docs/TableGen/BackGuide.rst @@ -4,9 +4,6 @@ TableGen Backend Developer's Guide .. sectnum:: -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst index 95a2b38dbf59a..39ffbec5f209d 100644 --- a/llvm/docs/TableGen/ProgRef.rst +++ b/llvm/docs/TableGen/ProgRef.rst @@ -4,9 +4,6 @@ TableGen Programmer's Reference .. sectnum:: -.. contents:: - :local: - Introduction ============ diff --git a/llvm/docs/Telemetry.rst b/llvm/docs/Telemetry.rst index c36105c99709f..52b41140a03ef 100644 --- a/llvm/docs/Telemetry.rst +++ b/llvm/docs/Telemetry.rst @@ -2,9 +2,6 @@ Telemetry framework in LLVM =========================== -.. contents:: - :local: - .. toctree:: :hidden: diff --git a/llvm/docs/TransformMetadata.rst b/llvm/docs/TransformMetadata.rst index 700761a383e9a..75d811db29dc1 100644 --- a/llvm/docs/TransformMetadata.rst +++ b/llvm/docs/TransformMetadata.rst @@ -4,9 +4,6 @@ Code Transformation Metadata ============================ -.. contents:: - :local: - Overview ======== diff --git a/llvm/docs/UndefinedBehavior.rst b/llvm/docs/UndefinedBehavior.rst index eddf954eddd2a..3e0240dd78626 100644 --- a/llvm/docs/UndefinedBehavior.rst +++ b/llvm/docs/UndefinedBehavior.rst @@ -2,10 +2,6 @@ LLVM IR Undefined Behavior (UB) Manual ====================================== -.. contents:: - :local: - :depth: 2 - Abstract ======== This document describes the undefined behavior (UB) in LLVM's IR, including diff --git a/llvm/docs/VectorizationPlan.rst b/llvm/docs/VectorizationPlan.rst index 20c621cf2ef42..e0211c3ce77af 100644 --- a/llvm/docs/VectorizationPlan.rst +++ b/llvm/docs/VectorizationPlan.rst @@ -2,9 +2,6 @@ Vectorization Plan ================== -.. contents:: - :local: - Abstract ======== The vectorization transformation can be rather complicated, involving several diff --git a/llvm/docs/Vectorizers.md b/llvm/docs/Vectorizers.md index d275cbeb31869..48e830617e557 100644 --- a/llvm/docs/Vectorizers.md +++ b/llvm/docs/Vectorizers.md @@ -1,9 +1,5 @@ # Auto-Vectorization in LLVM -```{contents} -:local: -``` - LLVM has two vectorizers: The {ref}`Loop Vectorizer `, which operates on Loops, and the {ref}`SLP Vectorizer `. These vectorizers diff --git a/llvm/docs/XRay.rst b/llvm/docs/XRay.rst index ceb5b88ab9108..48c8dbcccad4c 100644 --- a/llvm/docs/XRay.rst +++ b/llvm/docs/XRay.rst @@ -4,10 +4,6 @@ XRay Instrumentation :Version: 1 as of 2016-11-08 -.. contents:: - :local: - - Introduction ============ diff --git a/llvm/docs/XRayExample.rst b/llvm/docs/XRayExample.rst index 2260120480501..681ad1bc00426 100644 --- a/llvm/docs/XRayExample.rst +++ b/llvm/docs/XRayExample.rst @@ -6,9 +6,6 @@ This document shows an example of how you would go about analyzing applications built with XRay instrumentation. Here we will attempt to debug ``llc`` compiling some sample LLVM IR generated by Clang. -.. contents:: - :local: - Building with XRay ------------------ diff --git a/llvm/docs/XRayFDRFormat.rst b/llvm/docs/XRayFDRFormat.rst index b21b55496d753..7f33da8c1ba1d 100644 --- a/llvm/docs/XRayFDRFormat.rst +++ b/llvm/docs/XRayFDRFormat.rst @@ -4,10 +4,6 @@ XRay Flight Data Recorder Trace Format :Version: 1 as of 2017-07-20 -.. contents:: - :local: - - Introduction ============ diff --git a/llvm/docs/YamlIO.rst b/llvm/docs/YamlIO.rst index 553e4a830859a..52f86e9960dcd 100644 --- a/llvm/docs/YamlIO.rst +++ b/llvm/docs/YamlIO.rst @@ -2,9 +2,6 @@ YAML I/O ===================== -.. contents:: - :local: - Introduction to YAML ==================== diff --git a/llvm/docs/_static/LLVMWyvernSmall.png b/llvm/docs/_static/LLVMWyvernSmall.png new file mode 100644 index 0000000000000000000000000000000000000000..039e8d67931c6b6154d4608edab1a3293ebbb9e0 GIT binary patch literal 261036 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

roH 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ℜpPg+CvnD0t0~UDL?n);DhzE_V~?2B0P= zp-K^cZR=8~NAi-Ej~0TH+RXKXLqC)DYXx4ge^z5~Q!ab{NVa`!G3-Odsgw;3>$|7j3!1W{*r7{Cr zg#0KT-OwOMXH~WPM)!ZooSGBVZC2wQ4PpK*mm589Z`yRANxaH! z{sF>)r7sm?ZG9cK86EeUd+Yz1`dJh}Us!yUvMkkqpIBKK9u;ibUJi0YP02!~j#O6~ z50ac block. -(function () { - "use strict"; - - function addCopyButton(block) { - var button = document.createElement("button"); - button.className = "copybutton"; - button.title = "Copy"; - button.setAttribute("aria-label", "Copy code to clipboard"); - button.innerHTML = - ''; - - button.addEventListener("click", function () { - var code = block.querySelector("pre").innerText; - navigator.clipboard.writeText(code).then( - function () { - button.classList.add("copied"); - setTimeout(function () { - button.classList.remove("copied"); - }, 2000); - }, - function () { - // Fallback for older browsers - var ta = document.createElement("textarea"); - ta.value = code; - ta.style.position = "fixed"; - ta.style.opacity = "0"; - document.body.appendChild(ta); - ta.focus(); - ta.select(); - document.execCommand("copy"); - document.body.removeChild(ta); - button.classList.add("copied"); - setTimeout(function () { - button.classList.remove("copied"); - }, 2000); - } - ); - }); - - block.style.position = "relative"; - block.appendChild(button); - } - - document.addEventListener("DOMContentLoaded", function () { - document.querySelectorAll("div.highlight").forEach(addCopyButton); - }); -})(); diff --git a/llvm/docs/_static/custom.css b/llvm/docs/_static/custom.css deleted file mode 100644 index 60b2b5c9be1a7..0000000000000 --- a/llvm/docs/_static/custom.css +++ /dev/null @@ -1,62 +0,0 @@ -/* Enable flexible wide-viewing for Furo theme. */ -:root { - /* Remove Furo's default max-width for the content area. */ - --content-width: none; -} - -/* These settings seem to reasonably balance between readability and content - * density for wide screens. */ -.page .sidebar-drawer { - width: unset; -} -.main .toc-drawer { - min-width: 15em; -} - -/* Ensure the main content area is allowed to shrink/not-overflow - its grid cell, preventing it from pushing the TOC sidebar away. */ -.main, .content { - min-width: 0; - max-width: 100%; - - /* Remove default width setting from furo's content. */ - width: unset; -} - -/* Disable small margin added by various UA stylesheets to prevent - * scrolling artifacts. */ -body { - margin: 0; -} - -/* Allow the top-level container to fill the entire browser width. */ -.page { - max-width: none; -} - -/* Ensure wide tables and code blocks have their own scrollbars - instead of forcing the container to expand beyond the viewport. */ -.content table, -.content .literal-block, -.content .highlight { - max-width: 100%; - overflow-x: auto; - display: block; -} - -/* Ensure paragraphs wrap within the content area. */ -.content p { - overflow-wrap: break-word; -} - -/* Printing support. */ -@media print { - pre { - white-space: pre-wrap !important; - } - .content-icon-container, - .skip-to-content, - .back-to-top { - display: none !important; - } -} diff --git a/llvm/docs/conf.py b/llvm/docs/conf.py index f12ba64ec1203..a2e11e3d0b033 100644 --- a/llvm/docs/conf.py +++ b/llvm/docs/conf.py @@ -77,30 +77,26 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "furo" +html_theme = "llvm-theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = { - "source_repository": "https://github.com/llvm/llvm-project", - "source_branch": "main", - "source_directory": "llvm/docs/", -} +html_theme_options = {"nosidebar": False} # Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = ["_themes"] +html_theme_path = ["_themes"] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = "LLVM" +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = "_static/LLVMWyvernSmall.png" +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -112,13 +108,6 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] -html_js_files = ["copybutton.js"] - -html_css_files = [ - "copybutton.css", - "custom.css", -] - # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = "%Y-%m-%d" @@ -127,6 +116,16 @@ # typographically correct entities. # html_use_smartypants = True +# Custom sidebar templates, maps document names to template names. + +html_sidebars = { + "**": [ + "indexsidebar.html", + "sourcelink.html", + "searchbox.html", + ] +} + # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} diff --git a/llvm/docs/tutorial/BuildingAJIT1.rst b/llvm/docs/tutorial/BuildingAJIT1.rst index 52fc943aa687a..8d79eb9eb3ca2 100644 --- a/llvm/docs/tutorial/BuildingAJIT1.rst +++ b/llvm/docs/tutorial/BuildingAJIT1.rst @@ -2,6 +2,9 @@ Building a JIT: Starting out with KaleidoscopeJIT ======================================================= +.. contents:: + :local: + Chapter 1 Introduction ====================== diff --git a/llvm/docs/tutorial/BuildingAJIT2.rst b/llvm/docs/tutorial/BuildingAJIT2.rst index 580e82220ad1c..b8d397662576e 100644 --- a/llvm/docs/tutorial/BuildingAJIT2.rst +++ b/llvm/docs/tutorial/BuildingAJIT2.rst @@ -2,6 +2,9 @@ Building a JIT: Adding Optimizations -- An introduction to ORC Layers ===================================================================== +.. contents:: + :local: + **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/BuildingAJIT3.rst b/llvm/docs/tutorial/BuildingAJIT3.rst index 3e8d24b9e92bd..d4b3e6fb8eb36 100644 --- a/llvm/docs/tutorial/BuildingAJIT3.rst +++ b/llvm/docs/tutorial/BuildingAJIT3.rst @@ -2,6 +2,9 @@ Building a JIT: Per-function Lazy Compilation ============================================= +.. contents:: + :local: + **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/BuildingAJIT4.rst b/llvm/docs/tutorial/BuildingAJIT4.rst index e4ba22b183385..6eb3d52ccb8ab 100644 --- a/llvm/docs/tutorial/BuildingAJIT4.rst +++ b/llvm/docs/tutorial/BuildingAJIT4.rst @@ -2,6 +2,9 @@ Building a JIT: Extreme Laziness - Using LazyReexports to JIT from ASTs ======================================================================= +.. contents:: + :local: + **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst index da8d5ba1525bf..71ba9322817e0 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst @@ -2,6 +2,9 @@ Kaleidoscope: Kaleidoscope Introduction and the Lexer ===================================================== +.. contents:: + :local: + The Kaleidoscope Language ========================= diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst index 543bf58248948..eeb47a255a622 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst @@ -2,6 +2,9 @@ Kaleidoscope: Implementing a Parser and AST =========================================== +.. contents:: + :local: + Chapter 2 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst index 94dae2fb7e3dc..123f122af77e4 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst @@ -2,6 +2,9 @@ Kaleidoscope: Code generation to LLVM IR ======================================== +.. contents:: + :local: + Chapter 3 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst index d36cb05035c8b..3d954e744f5c8 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst @@ -2,6 +2,9 @@ Kaleidoscope: Adding JIT and Optimizer Support ============================================== +.. contents:: + :local: + Chapter 4 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst index e0bf85b3a3667..0039547e8c7ba 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst @@ -2,6 +2,9 @@ Kaleidoscope: Extending the Language: Control Flow ================================================== +.. contents:: + :local: + Chapter 5 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst index f78943b98a1a6..066693eb963a5 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst @@ -2,6 +2,9 @@ Kaleidoscope: Extending the Language: User-defined Operators ============================================================ +.. contents:: + :local: + Chapter 6 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst index 0e815786a30b0..f7e7572367448 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst @@ -2,6 +2,9 @@ Kaleidoscope: Extending the Language: Mutable Variables ======================================================= +.. contents:: + :local: + Chapter 7 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst index cc5aadb6e2dbf..2e3d4ed0a3087 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst @@ -2,6 +2,9 @@ Kaleidoscope: Compiling to Object Code ======================================== +.. contents:: + :local: + Chapter 8 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst index 5d25620372633..a88b6ed48e8d4 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst @@ -2,6 +2,9 @@ Kaleidoscope: Adding Debug Information ====================================== +.. contents:: + :local: + Chapter 9 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst index b4c7edbd1fa40..a739936b86608 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst @@ -2,6 +2,9 @@ Kaleidoscope: Conclusion and other useful LLVM tidbits ====================================================== +.. contents:: + :local: + Tutorial Conclusion =================== From 1d73e32bf36b98cce9dda0d5fba482aa81a88d1d Mon Sep 17 00:00:00 2001 From: David Green Date: Fri, 10 Jul 2026 06:01:43 +0100 Subject: [PATCH 069/125] [AArch64][GlobalISel] Update scalar types in postlegalizer tests. NFC (#208620) --- .../postlegalizer-combine-ptr-add-chain.mir | 24 +- ...ostlegalizer-combiner-and-trivial-mask.mir | 224 ++++++------ .../postlegalizer-combiner-anyext-to-zext.mir | 64 ++-- .../postlegalizer-combiner-constant-fold.mir | 216 +++++------ .../postlegalizer-combiner-copy-prop.mir | 20 +- .../postlegalizer-combiner-identity.mir | 12 +- .../postlegalizer-combiner-merge.mir | 58 +-- ...legalizer-combiner-redundant-sextinreg.mir | 54 +-- ...alizer-combiner-sameopcode-hands-crash.mir | 28 +- ...stlegalizer-combiner-split-zero-stores.mir | 82 ++--- .../postlegalizer-combiner-undef.mir | 14 +- .../postlegalizer-combiner-unmergedup.mir | 82 ++--- ...postlegalizer-lowering-adjust-icmp-imm.mir | 320 ++++++++-------- .../GlobalISel/postlegalizer-lowering-ext.mir | 216 +++++------ .../GlobalISel/postlegalizer-lowering-rev.mir | 48 +-- .../postlegalizer-lowering-sextinreg.mir | 26 +- .../postlegalizer-lowering-shuf-to-ins.mir | 174 ++++----- ...postlegalizer-lowering-shuffle-duplane.mir | 78 ++-- .../postlegalizer-lowering-shuffle-splat.mir | 346 +++++++++--------- .../GlobalISel/postlegalizer-lowering-trn.mir | 160 ++++---- .../postlegalizer-lowering-truncstore.mir | 34 +- .../postlegalizer-lowering-unmerge-ext.mir | 149 ++++---- .../GlobalISel/postlegalizer-lowering-uzp.mir | 96 ++--- .../postlegalizer-lowering-vashr-vlshr.mir | 112 +++--- .../GlobalISel/postlegalizer-lowering-zip.mir | 142 +++---- .../postlegalizercombiner-extending-loads.mir | 16 +- ...postlegalizercombiner-extractvec-faddp.mir | 152 ++++---- ...postlegalizercombiner-hoist-same-hands.mir | 70 ++-- .../postlegalizercombiner-mulpow2.mir | 18 +- .../postlegalizercombiner-rotate.mir | 64 ++-- .../postlegalizercombiner-select.mir | 54 +-- 31 files changed, 1565 insertions(+), 1588 deletions(-) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir index ec64c9e02791d..bea2d7a08fd44 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combine-ptr-add-chain.mir @@ -16,13 +16,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = G_PTR_ADD %0(p0), %1 %4:_(p0) = G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) @@ -40,13 +40,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = nuw G_PTR_ADD %0(p0), %1 %4:_(p0) = nuw G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) @@ -64,13 +64,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](s64) + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = nuw nusw inbounds G_PTR_ADD [[COPY]], [[C]](i64) ; CHECK-NEXT: $x0 = COPY [[PTR_ADD]](p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 %0:_(p0) = COPY $x0 - %1:_(s64) = G_CONSTANT i64 4 - %2:_(s64) = G_CONSTANT i64 12 + %1:_(i64) = G_CONSTANT i64 4 + %2:_(i64) = G_CONSTANT i64 12 %3:_(p0) = nuw nusw inbounds G_PTR_ADD %0(p0), %1 %4:_(p0) = nuw nusw inbounds G_PTR_ADD %3(p0), %2 $x0 = COPY %4(p0) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir index 1f7d5e7ed434e..5dc61236279dc 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-and-trivial-mask.mir @@ -19,17 +19,17 @@ body: | ; CHECK-LABEL: name: remove_and_with_one_bit ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - ; CHECK-NEXT: $w0 = COPY %cmp(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + ; CHECK-NEXT: $w0 = COPY %cmp(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - %mask:_(s32) = G_CONSTANT i32 1 - %and:_(s32) = G_AND %cmp(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + %mask:_(i32) = G_CONSTANT i32 1 + %and:_(i32) = G_AND %cmp(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -44,17 +44,17 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_mask ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: $w0 = COPY %z(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: $w0 = COPY %z(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %mask:_(s32) = G_CONSTANT i32 -1 - %and:_(s32) = G_AND %z(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %mask:_(i32) = G_CONSTANT i32 -1 + %and:_(i32) = G_AND %z(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -72,19 +72,19 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_zext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_ZEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_ZEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -99,19 +99,19 @@ body: | ; CHECK-LABEL: name: remove_and_all_ones_anyext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_ZEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_ZEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -127,21 +127,21 @@ body: | ; CHECK-LABEL: name: dont_remove_all_ones_sext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32) - ; CHECK-NEXT: %mask:_(s64) = G_CONSTANT i64 4294967295 - ; CHECK-NEXT: %and:_(s64) = G_AND %ext, %mask - ; CHECK-NEXT: $x0 = COPY %and(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %ext:_(i64) = G_SEXT %z(i32) + ; CHECK-NEXT: %mask:_(i64) = G_CONSTANT i64 4294967295 + ; CHECK-NEXT: %and:_(i64) = G_AND %ext, %mask + ; CHECK-NEXT: $x0 = COPY %and(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %ext:_(s64) = G_SEXT %z - %mask:_(s64) = G_CONSTANT i64 4294967295 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %ext:_(i64) = G_SEXT %z + %mask:_(i64) = G_CONSTANT i64 4294967295 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -159,19 +159,19 @@ body: | ; CHECK-LABEL: name: remove_and_positive_constant_sext ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = G_CONSTANT i32 42 - ; CHECK-NEXT: %ext:_(s64) = G_SEXT %z(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = G_CONSTANT i32 42 + ; CHECK-NEXT: %ext:_(i64) = G_SEXT %z(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = G_CONSTANT i32 42 - %ext:_(s64) = G_SEXT %z - %mask:_(s64) = G_CONSTANT i64 63 - %and:_(s64) = G_AND %ext(s64), %mask - $x0 = COPY %and(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = G_CONSTANT i32 42 + %ext:_(i64) = G_SEXT %z + %mask:_(i64) = G_CONSTANT i64 63 + %and:_(i64) = G_AND %ext(i64), %mask + $x0 = COPY %and(i64) RET_ReallyLR implicit $x0 ... @@ -186,19 +186,19 @@ body: | ; CHECK-LABEL: name: not_a_mask ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %and:_(s32) = G_AND %cmp, %mask - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + ; CHECK-NEXT: %mask:_(i32) = G_CONSTANT i32 6 + ; CHECK-NEXT: %and:_(i32) = G_AND %cmp, %mask + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %cmp:_(s32) = G_ICMP intpred(eq), %x(s32), %y - %mask:_(s32) = G_CONSTANT i32 6 - %and:_(s32) = G_AND %cmp(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %cmp:_(i32) = G_ICMP intpred(eq), %x(i32), %y + %mask:_(i32) = G_CONSTANT i32 6 + %and:_(i32) = G_AND %cmp(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... @@ -214,19 +214,19 @@ body: | ; CHECK-LABEL: name: unknown_val ; CHECK: liveins: $w0, $w1, $w2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %z:_(s32) = COPY $w2 - ; CHECK-NEXT: %one:_(s32) = G_CONSTANT i32 32 - ; CHECK-NEXT: %and:_(s32) = G_AND %z, %one - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %z:_(i32) = COPY $w2 + ; CHECK-NEXT: %one:_(i32) = G_CONSTANT i32 32 + ; CHECK-NEXT: %and:_(i32) = G_AND %z, %one + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %z:_(s32) = COPY $w2 - %one:_(s32) = G_CONSTANT i32 32 - %and:_(s32) = G_AND %z(s32), %one - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %z:_(i32) = COPY $w2 + %one:_(i32) = G_CONSTANT i32 32 + %and:_(i32) = G_AND %z(i32), %one + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... --- @@ -242,15 +242,15 @@ body: | ; CHECK-LABEL: name: remove_and_assert_zext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 8 - ; CHECK-NEXT: $w0 = COPY %assert_zext(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_zext:_(i32) = G_ASSERT_ZEXT %x, 8 + ; CHECK-NEXT: $w0 = COPY %assert_zext(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 8 - %mask:_(s32) = G_CONSTANT i32 255 - %and:_(s32) = G_AND %assert_zext(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %assert_zext:_(i32) = G_ASSERT_ZEXT %x(i32), 8 + %mask:_(i32) = G_CONSTANT i32 255 + %and:_(i32) = G_AND %assert_zext(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 ... --- @@ -265,15 +265,15 @@ body: | ; CHECK-LABEL: name: dont_remove_and_assert_zext_wrong_mask ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_zext:_(s32) = G_ASSERT_ZEXT %x, 16 - ; CHECK-NEXT: %mask:_(s32) = G_CONSTANT i32 255 - ; CHECK-NEXT: %and:_(s32) = G_AND %assert_zext, %mask - ; CHECK-NEXT: $w0 = COPY %and(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_zext:_(i32) = G_ASSERT_ZEXT %x, 16 + ; CHECK-NEXT: %mask:_(i32) = G_CONSTANT i32 255 + ; CHECK-NEXT: %and:_(i32) = G_AND %assert_zext, %mask + ; CHECK-NEXT: $w0 = COPY %and(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %assert_zext:_(s32) = G_ASSERT_ZEXT %x(s32), 16 - %mask:_(s32) = G_CONSTANT i32 255 - %and:_(s32) = G_AND %assert_zext(s32), %mask - $w0 = COPY %and(s32) + %x:_(i32) = COPY $w0 + %assert_zext:_(i32) = G_ASSERT_ZEXT %x(i32), 16 + %mask:_(i32) = G_CONSTANT i32 255 + %and:_(i32) = G_AND %assert_zext(i32), %mask + $w0 = COPY %and(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir index 24baa2fc13317..69d2f9f0cd3bb 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-anyext-to-zext.mir @@ -15,17 +15,17 @@ body: | ; CHECK-LABEL: name: scalar_icmp ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s64) = COPY $x0 - ; CHECK-NEXT: %cst_1:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %icmp:_(s32) = G_ICMP intpred(eq), %copy(s64), %cst_1 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %icmp(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %copy:_(i64) = COPY $x0 + ; CHECK-NEXT: %cst_1:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: %icmp:_(i32) = G_ICMP intpred(eq), %copy(i64), %cst_1 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %icmp(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:_(s64) = COPY $x0 - %cst_1:_(s64) = G_CONSTANT i64 1 - %icmp:_(s32) = G_ICMP intpred(eq), %copy(s64), %cst_1 - %ext:_(s64) = G_ANYEXT %icmp(s32) - $x0 = COPY %ext(s64) + %copy:_(i64) = COPY $x0 + %cst_1:_(i64) = G_CONSTANT i64 1 + %icmp:_(i32) = G_ICMP intpred(eq), %copy(i64), %cst_1 + %ext:_(i64) = G_ANYEXT %icmp(i32) + $x0 = COPY %ext(i64) RET_ReallyLR implicit $x0 @@ -42,19 +42,19 @@ body: | ; CHECK-LABEL: name: vector_icmp ; CHECK: liveins: $x0, $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %cst_1:_(s32) = G_CONSTANT i32 1 - ; CHECK-NEXT: %vec_cst_1:_(<2 x s32>) = G_BUILD_VECTOR %cst_1(s32), %cst_1(s32) - ; CHECK-NEXT: %icmp:_(<2 x s32>) = G_ICMP intpred(eq), %copy(<2 x s32>), %vec_cst_1 - ; CHECK-NEXT: %ext:_(<2 x s64>) = G_ANYEXT %icmp(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %ext(<2 x s64>) + ; CHECK-NEXT: %copy:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %cst_1:_(i32) = G_CONSTANT i32 1 + ; CHECK-NEXT: %vec_cst_1:_(<2 x i32>) = G_BUILD_VECTOR %cst_1(i32), %cst_1(i32) + ; CHECK-NEXT: %icmp:_(<2 x i32>) = G_ICMP intpred(eq), %copy(<2 x i32>), %vec_cst_1 + ; CHECK-NEXT: %ext:_(<2 x i64>) = G_ANYEXT %icmp(<2 x i32>) + ; CHECK-NEXT: $q0 = COPY %ext(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %copy:_(<2 x s32>) = COPY $d0 - %cst_1:_(s32) = G_CONSTANT i32 1 - %vec_cst_1:_(<2 x s32>) = G_BUILD_VECTOR %cst_1, %cst_1 - %icmp:_(<2 x s32>) = G_ICMP intpred(eq), %copy(<2 x s32>), %vec_cst_1 - %ext:_(<2 x s64>) = G_ANYEXT %icmp(<2 x s32>) - $q0 = COPY %ext(<2 x s64>) + %copy:_(<2 x i32>) = COPY $d0 + %cst_1:_(i32) = G_CONSTANT i32 1 + %vec_cst_1:_(<2 x i32>) = G_BUILD_VECTOR %cst_1, %cst_1 + %icmp:_(<2 x i32>) = G_ICMP intpred(eq), %copy(<2 x i32>), %vec_cst_1 + %ext:_(<2 x i64>) = G_ANYEXT %icmp(<2 x i32>) + $q0 = COPY %ext(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -70,15 +70,15 @@ body: | ; CHECK-LABEL: name: scalar_fcmp ; CHECK: liveins: $x0, $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s64) = COPY $d0 - ; CHECK-NEXT: %cst_1:_(s64) = G_FCONSTANT double 1.000000e+00 - ; CHECK-NEXT: %fcmp:_(s32) = G_FCMP intpred(eq), %copy(s64), %cst_1 - ; CHECK-NEXT: %ext:_(s64) = G_ZEXT %fcmp(s32) - ; CHECK-NEXT: $x0 = COPY %ext(s64) + ; CHECK-NEXT: %copy:_(f64) = COPY $d0 + ; CHECK-NEXT: %cst_1:_(f64) = G_FCONSTANT double 1.000000e+00 + ; CHECK-NEXT: %fcmp:_(i32) = G_FCMP intpred(eq), %copy(f64), %cst_1 + ; CHECK-NEXT: %ext:_(i64) = G_ZEXT %fcmp(i32) + ; CHECK-NEXT: $x0 = COPY %ext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %copy:_(s64) = COPY $d0 - %cst_1:_(s64) = G_FCONSTANT double 1.0 - %fcmp:_(s32) = G_FCMP intpred(eq), %copy(s64), %cst_1 - %ext:_(s64) = G_ANYEXT %fcmp(s32) - $x0 = COPY %ext(s64) + %copy:_(f64) = COPY $d0 + %cst_1:_(f64) = G_FCONSTANT double 1.0 + %fcmp:_(i32) = G_FCMP intpred(eq), %copy(f64), %cst_1 + %ext:_(i64) = G_ANYEXT %fcmp(i32) + $x0 = COPY %ext(i64) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir index 0435baaf30f01..45b503d28cabe 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-constant-fold.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: add ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 42 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 42 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_ADD %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_ADD %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -37,13 +37,13 @@ body: | ; CHECK-LABEL: name: sub ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 38 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 38 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_SUB %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_SUB %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -60,13 +60,13 @@ body: | ; CHECK-LABEL: name: mul ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 80 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 80 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_MUL %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_MUL %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -83,13 +83,13 @@ body: | ; CHECK-LABEL: name: and ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 40 - %b:_(s64) = G_CONSTANT i64 2 - %res:_(s64) = G_AND %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 40 + %b:_(i64) = G_CONSTANT i64 2 + %res:_(i64) = G_AND %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -106,13 +106,13 @@ body: | ; CHECK-LABEL: name: or ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 62 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 62 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 42 - %b:_(s64) = G_CONSTANT i64 22 - %res:_(s64) = G_OR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 42 + %b:_(i64) = G_CONSTANT i64 22 + %res:_(i64) = G_OR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -129,13 +129,13 @@ body: | ; CHECK-LABEL: name: xor ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_CONSTANT i64 12 - ; CHECK-NEXT: $x0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(i64) = G_CONSTANT i64 12 + ; CHECK-NEXT: $x0 = COPY %res(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = G_CONSTANT i64 8 - %b:_(s64) = G_CONSTANT i64 4 - %res:_(s64) = G_XOR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = G_CONSTANT i64 8 + %b:_(i64) = G_CONSTANT i64 4 + %res:_(i64) = G_XOR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... @@ -151,13 +151,13 @@ body: | ; CHECK-LABEL: name: fadd ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 4.200000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 4.200000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FADD %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FADD %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -173,13 +173,13 @@ body: | ; CHECK-LABEL: name: fsub ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 3.800000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 3.800000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FSUB %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FSUB %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -195,13 +195,13 @@ body: | ; CHECK-LABEL: name: fmul ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 8.000000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 8.000000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FMUL %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FMUL %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -217,13 +217,13 @@ body: | ; CHECK-LABEL: name: fdiv ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double 2.000000e+01 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 2.000000e+01 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 40.0 - %b:_(s64) = G_FCONSTANT double 2.0 - %res:_(s64) = G_FDIV %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 40.0 + %b:_(f64) = G_FCONSTANT double 2.0 + %res:_(f64) = G_FDIV %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -239,13 +239,13 @@ body: | ; CHECK-LABEL: name: fminimumnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINIMUMNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINIMUMNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -261,13 +261,13 @@ body: | ; CHECK-LABEL: name: fmaximumnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXIMUMNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXIMUMNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -284,13 +284,13 @@ body: | ; CHECK-LABEL: name: fcopysign ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s64) = G_FCONSTANT double -3.000000e+00 - ; CHECK-NEXT: $d0 = COPY %res(s64) + ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double -3.000000e+00 + ; CHECK-NEXT: $d0 = COPY %res(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 3.0 - %b:_(s64) = G_FCONSTANT double -1.0 - %res:_(s64) = G_FCOPYSIGN %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 3.0 + %b:_(f64) = G_FCONSTANT double -1.0 + %res:_(f64) = G_FCOPYSIGN %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -307,13 +307,13 @@ body: | ; CHECK-LABEL: name: fminnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -330,13 +330,13 @@ body: | ; CHECK-LABEL: name: fmaxnum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXNUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXNUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -353,13 +353,13 @@ body: | ; CHECK-LABEL: name: fminimum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = G_FCONSTANT double 2.000000e+00 - ; CHECK-NEXT: $d0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(f64) = G_FCONSTANT double 2.000000e+00 + ; CHECK-NEXT: $d0 = COPY %a(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMINIMUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMINIMUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -376,13 +376,13 @@ body: | ; CHECK-LABEL: name: fmaximum ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %b:_(s64) = G_FCONSTANT double 5.000000e+00 - ; CHECK-NEXT: $d0 = COPY %b(s64) + ; CHECK-NEXT: %b:_(f64) = G_FCONSTANT double 5.000000e+00 + ; CHECK-NEXT: $d0 = COPY %b(f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %a:_(s64) = G_FCONSTANT double 2.0 - %b:_(s64) = G_FCONSTANT double 5.0 - %res:_(s64) = G_FMAXIMUM %a, %b - $d0 = COPY %res(s64) + %a:_(f64) = G_FCONSTANT double 2.0 + %b:_(f64) = G_FCONSTANT double 5.0 + %res:_(f64) = G_FMAXIMUM %a, %b + $d0 = COPY %res(f64) RET_ReallyLR implicit $d0 ... @@ -398,13 +398,13 @@ body: | ; CHECK-LABEL: name: fadd32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %res:_(s32) = G_FCONSTANT float 4.200000e+01 - ; CHECK-NEXT: $s0 = COPY %res(s32) + ; CHECK-NEXT: %res:_(i32) = G_FCONSTANT float 4.200000e+01 + ; CHECK-NEXT: $s0 = COPY %res(i32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %a:_(s32) = G_FCONSTANT float 40.0 - %b:_(s32) = G_FCONSTANT float 2.0 - %res:_(s32) = G_FADD %a, %b - $s0 = COPY %res(s32) + %a:_(i32) = G_FCONSTANT float 40.0 + %b:_(i32) = G_FCONSTANT float 2.0 + %res:_(i32) = G_FADD %a, %b + $s0 = COPY %res(i32) RET_ReallyLR implicit $s0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir index d867fc4341b4e..ff141a383c563 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-copy-prop.mir @@ -13,17 +13,17 @@ body: | ; CHECK-LABEL: name: postlegalize_copy_prop ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]] - ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(s64) = G_ADD [[ADD]], [[ADD]] - ; CHECK-NEXT: $x0 = COPY [[ADD1]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(i64) = G_ADD [[COPY]], [[COPY1]] + ; CHECK-NEXT: [[ADD1:%[0-9]+]]:_(i64) = G_ADD [[ADD]], [[ADD]] + ; CHECK-NEXT: $x0 = COPY [[ADD1]](i64) ; CHECK-NEXT: RET_ReallyLR - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = G_ADD %0, %1 - %3:_(s64) = COPY %2 - %4:_(s64) = G_ADD %3, %3 + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i64) = G_ADD %0, %1 + %3:_(i64) = COPY %2 + %4:_(i64) = G_ADD %3, %3 $x0 = COPY %4 RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir index 0d36f5c8d8c03..540012453f79b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-identity.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: shift_of_zero ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %a:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY %a(s64) + ; CHECK-NEXT: %a:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY %a(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %a:_(s64) = COPY $x0 - %b:_(s64) = G_CONSTANT i64 0 - %res:_(s64) = G_LSHR %a, %b - $x0 = COPY %res(s64) + %a:_(i64) = COPY $x0 + %b:_(i64) = G_CONSTANT i64 0 + %res:_(i64) = G_LSHR %a, %b + $x0 = COPY %res(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir index 9e7c573cd8a5f..041ef55fed637 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-merge.mir @@ -14,13 +14,13 @@ body: | ; CHECK-LABEL: name: merge_unmerge ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s64) = COPY $x0 - %a:_(s32), %b:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i64) = COPY $x0 + %a:_(i32), %b:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -37,15 +37,15 @@ body: | ; CHECK-LABEL: name: merge_unmerge_mismatched_order ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES [[COPY]](s64) - ; CHECK-NEXT: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: %b:_(i32), %a:_(i32) = G_UNMERGE_VALUES [[COPY]](i64) + ; CHECK-NEXT: %merge:_(i64) = G_MERGE_VALUES %a(i32), %b(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s64) = COPY $x0 - %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i64) = COPY $x0 + %b:_(i32), %a:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -62,15 +62,15 @@ body: | ; CHECK-LABEL: name: merge_unmerge_mismatched_num_defs ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s128) = COPY $q0 - ; CHECK-NEXT: %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES [[COPY]](s128) - ; CHECK-NEXT: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i128) = COPY $q0 + ; CHECK-NEXT: %a:_(i32), %b:_(i32), %c:_(i32), %d:_(i32) = G_UNMERGE_VALUES [[COPY]](i128) + ; CHECK-NEXT: %merge:_(i64) = G_MERGE_VALUES %a(i32), %b(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(s128) = COPY $q0 - %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES %0 - %merge:_(s64) = G_MERGE_VALUES %a, %b - $x0 = COPY %merge(s64) + %0:_(i128) = COPY $q0 + %a:_(i32), %b:_(i32), %c:_(i32), %d:_(i32) = G_UNMERGE_VALUES %0 + %merge:_(i64) = G_MERGE_VALUES %a, %b + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... @@ -87,14 +87,14 @@ body: | ; CHECK-LABEL: name: merge_to_zext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v:_(s32) = COPY $w0 - ; CHECK-NEXT: %merge:_(s64) = G_ZEXT %v(s32) - ; CHECK-NEXT: $x0 = COPY %merge(s64) + ; CHECK-NEXT: %v:_(i32) = COPY $w0 + ; CHECK-NEXT: %merge:_(i64) = G_ZEXT %v(i32) + ; CHECK-NEXT: $x0 = COPY %merge(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %v:_(s32) = COPY $w0 - %zero:_(s32) = G_CONSTANT i32 0 - %merge:_(s64) = G_MERGE_VALUES %v, %zero - $x0 = COPY %merge(s64) + %v:_(i32) = COPY $w0 + %zero:_(i32) = G_CONSTANT i32 0 + %merge:_(i64) = G_MERGE_VALUES %v, %zero + $x0 = COPY %merge(i64) RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir index 5da796c637c97..90af83c768848 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-redundant-sextinreg.mir @@ -14,12 +14,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %x0:_(p0) = COPY $x0 - ; CHECK-NEXT: %sextload:_(s32) = G_SEXTLOAD %x0(p0) :: (load (s16)) - ; CHECK-NEXT: $w0 = COPY %sextload(s32) + ; CHECK-NEXT: %sextload:_(i32) = G_SEXTLOAD %x0(p0) :: (load (i16)) + ; CHECK-NEXT: $w0 = COPY %sextload(i32) %x0:_(p0) = COPY $x0 - %sextload:_(s32) = G_SEXTLOAD %x0:_(p0) :: (load (s16)) - %sext_inreg:_(s32) = G_SEXT_INREG %sextload:_(s32), 24 - $w0 = COPY %sext_inreg(s32) + %sextload:_(i32) = G_SEXTLOAD %x0:_(p0) :: (load (i16)) + %sext_inreg:_(i32) = G_SEXT_INREG %sextload:_(i32), 24 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext @@ -34,13 +34,13 @@ body: | ; CHECK-LABEL: name: assert_sext ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - ; CHECK-NEXT: $w0 = COPY %assert_sext(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 24 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + ; CHECK-NEXT: $w0 = COPY %assert_sext(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 24 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext_greater_width @@ -55,14 +55,14 @@ body: | ; CHECK-LABEL: name: assert_sext_greater_width ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - ; CHECK-NEXT: %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext, 12 - ; CHECK-NEXT: $w0 = COPY %sext_inreg(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 24 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 12 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + ; CHECK-NEXT: %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext, 12 + ; CHECK-NEXT: $w0 = COPY %sext_inreg(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 24 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 12 + $w0 = COPY %sext_inreg(i32) ... --- name: assert_sext_smaller_width @@ -77,11 +77,11 @@ body: | ; CHECK-LABEL: name: assert_sext_smaller_width ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %w0:_(s32) = COPY $w0 - ; CHECK-NEXT: %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 8 - ; CHECK-NEXT: $w0 = COPY %assert_sext(s32) - %w0:_(s32) = COPY $w0 - %assert_sext:_(s32) = G_ASSERT_SEXT %w0, 8 - %sext_inreg:_(s32) = G_SEXT_INREG %assert_sext:_(s32), 12 - $w0 = COPY %sext_inreg(s32) + ; CHECK-NEXT: %w0:_(i32) = COPY $w0 + ; CHECK-NEXT: %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 8 + ; CHECK-NEXT: $w0 = COPY %assert_sext(i32) + %w0:_(i32) = COPY $w0 + %assert_sext:_(i32) = G_ASSERT_SEXT %w0, 8 + %sext_inreg:_(i32) = G_SEXT_INREG %assert_sext:_(i32), 12 + $w0 = COPY %sext_inreg(i32) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir index 2d286ede38d5d..c9af72dab2293 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-sameopcode-hands-crash.mir @@ -9,22 +9,22 @@ body: | bb.1: ; CHECK-LABEL: name: crash_fn ; CHECK: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s1) = G_CONSTANT i1 false - ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[C]](p0) :: (load (s16), align 8) - ; CHECK-NEXT: [[ZEXTLOAD1:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[C]](p0) :: (load (s16)) - ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[ZEXTLOAD1]], [[ZEXTLOAD]] - ; CHECK-NEXT: $w0 = COPY [[AND]](s32) + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i1) = G_CONSTANT i1 false + ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[C]](p0) :: (load (i16), align 8) + ; CHECK-NEXT: [[ZEXTLOAD1:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[C]](p0) :: (load (i16)) + ; CHECK-NEXT: [[AND:%[0-9]+]]:_(i32) = G_AND [[ZEXTLOAD1]], [[ZEXTLOAD]] + ; CHECK-NEXT: $w0 = COPY [[AND]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 %1:_(p0) = G_CONSTANT i64 0 - %6:_(s32) = G_CONSTANT i32 0 - %9:_(s1) = G_CONSTANT i1 false - %0:_(s16) = G_LOAD %1(p0) :: (load (s16), align 8) - %2:_(s32) = G_ZEXT %0(s16) - %3:_(s16) = G_LOAD %1(p0) :: (load (s16)) - %4:_(s32) = G_ZEXT %3(s16) - %5:_(s32) = G_AND %4, %2 - $w0 = COPY %5(s32) + %6:_(i32) = G_CONSTANT i32 0 + %9:_(i1) = G_CONSTANT i1 false + %0:_(i16) = G_LOAD %1(p0) :: (load (i16), align 8) + %2:_(i32) = G_ZEXT %0(i16) + %3:_(i16) = G_LOAD %1(p0) :: (load (i16)) + %4:_(i32) = G_ZEXT %3(i16) + %5:_(i32) = G_AND %4, %2 + $w0 = COPY %5(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir index 5c6f057a39317..05efb5fa4388f 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-split-zero-stores.mir @@ -16,16 +16,16 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 8 ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](i64) - ; CHECK-NEXT: G_STORE [[C]](i64), [[COPY]](p0) :: (store (i64), align 16) - ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) + ; CHECK-NEXT: G_STORE %zero(i64), [[COPY]](p0) :: (store (i64), align 16) + ; CHECK-NEXT: G_STORE %zero(i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i64>)) RET_ReallyLR ... @@ -48,9 +48,9 @@ body: | ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s32) = G_CONSTANT i32 0 - %zerovec:_(<4 x s32>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero - G_STORE %zerovec(<4 x s32>), %0(p0) :: (store (<4 x s32>)) + %zero:_(i32) = G_CONSTANT i32 0 + %zerovec:_(<4 x i32>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero + G_STORE %zerovec(<4 x i32>), %0(p0) :: (store (<4 x i32>)) RET_ReallyLR ... @@ -73,9 +73,9 @@ body: | ; CHECK-NEXT: G_STORE [[C]](i64), [[PTR_ADD]](p0) :: (store (i64) into unknown-address + 8) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s16) = G_CONSTANT i16 0 - %zerovec:_(<8 x s16>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero, %zero, %zero, %zero, %zero - G_STORE %zerovec(<8 x s16>), %0(p0) :: (store (<8 x s16>)) + %zero:_(i16) = G_CONSTANT i16 0 + %zerovec:_(<8 x i16>) = G_BUILD_VECTOR %zero, %zero, %zero, %zero, %zero, %zero, %zero, %zero + G_STORE %zerovec(<8 x i16>), %0(p0) :: (store (<8 x i16>)) RET_ReallyLR ... @@ -93,14 +93,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: %zerovec:_(<2 x s32>) = G_BUILD_VECTOR %zero(s32), %zero(s32) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s32>), [[COPY]](p0) :: (store (<2 x s32>)) + ; CHECK-NEXT: %zero:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: %zerovec:_(<2 x i32>) = G_BUILD_VECTOR %zero(i32), %zero(i32) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i32>), [[COPY]](p0) :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s32) = G_CONSTANT i32 0 - %zerovec:_(<2 x s32>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s32>), %0(p0) :: (store (<2 x s32>)) + %zero:_(i32) = G_CONSTANT i32 0 + %zerovec:_(<2 x i32>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i32>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -116,15 +116,15 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (store (<2 x s64>)) - ; CHECK-NEXT: $q0 = COPY %zerovec(<2 x s64>) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (store (<2 x i64>)) + ; CHECK-NEXT: $q0 = COPY %zerovec(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i64>)) $q0 = COPY %zerovec RET_ReallyLR @@ -141,14 +141,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (store (<2 x s32>)) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (store (<2 x i32>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (store (<2 x s32>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (store (<2 x i32>)) RET_ReallyLR ... @@ -164,14 +164,14 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero(s64), %zero(s64) - ; CHECK-NEXT: G_STORE %zerovec(<2 x s64>), [[COPY]](p0) :: (volatile store (<2 x s64>)) + ; CHECK-NEXT: %zero:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero(i64), %zero(i64) + ; CHECK-NEXT: G_STORE %zerovec(<2 x i64>), [[COPY]](p0) :: (volatile store (<2 x i64>)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s64) = G_CONSTANT i64 0 - %zerovec:_(<2 x s64>) = G_BUILD_VECTOR %zero, %zero - G_STORE %zerovec(<2 x s64>), %0(p0) :: (volatile store (<2 x s64>)) + %zero:_(i64) = G_CONSTANT i64 0 + %zerovec:_(<2 x i64>) = G_BUILD_VECTOR %zero, %zero + G_STORE %zerovec(<2 x i64>), %0(p0) :: (volatile store (<2 x i64>)) RET_ReallyLR ... @@ -189,12 +189,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: %zero:_(s128) = G_CONSTANT i128 0 - ; CHECK-NEXT: G_STORE %zero(s128), [[COPY]](p0) :: (store (s128)) + ; CHECK-NEXT: %zero:_(i128) = G_CONSTANT i128 0 + ; CHECK-NEXT: G_STORE %zero(i128), [[COPY]](p0) :: (store (i128)) ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %zero:_(s128) = G_CONSTANT i128 0 - G_STORE %zero(s128), %0(p0) :: (store (s128)) + %zero:_(i128) = G_CONSTANT i128 0 + G_STORE %zero(i128), %0(p0) :: (store (i128)) RET_ReallyLR ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir index 085a6694995ff..bc65891cec7ce 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-undef.mir @@ -18,8 +18,8 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: RET_ReallyLR %0:_(p0) = COPY $x0 - %1:_(s32) = G_IMPLICIT_DEF - G_STORE %1(s32), %0(p0) :: (store (s32)) + %1:_(i32) = G_IMPLICIT_DEF + G_STORE %1(i32), %0(p0) :: (store (i32)) RET_ReallyLR ... @@ -34,12 +34,12 @@ body: | ; CHECK-LABEL: name: delete_add_undef ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF - ; CHECK-NEXT: $x0 = COPY [[DEF]](s64) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(i64) = G_IMPLICIT_DEF + ; CHECK-NEXT: $x0 = COPY [[DEF]](i64) ; CHECK-NEXT: RET_ReallyLR - %0:_(s64) = COPY $x0 - %1:_(s64) = G_IMPLICIT_DEF - %add:_(s64) = G_ADD %0(s64), %1(s64) + %0:_(i64) = COPY $x0 + %1:_(i64) = G_IMPLICIT_DEF + %add:_(i64) = G_ADD %0(i64), %1(i64) $x0 = COPY %add RET_ReallyLR diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir index 1a9f8ed88ef4b..57d0e93ef4334 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir @@ -7,17 +7,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup8 - ; CHECK: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE8_1:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE8_]](<8 x s8>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_1]](<8 x s8>) + ; CHECK: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<8 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE8_1:%[0-9]+]]:_(<8 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE8_]](<8 x i8>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_1]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<16 x s8>) = G_DUPLANE8 %0, %1 - %3:_(<8 x s8>), %4:_(<8 x s8>) = G_UNMERGE_VALUES %2 + %0:_(<16 x i8>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<16 x i8>) = G_DUPLANE8 %0, %1 + %3:_(<8 x i8>), %4:_(<8 x i8>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -29,17 +29,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup16 - ; CHECK: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE16_1:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE16_]](<4 x s16>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_1]](<4 x s16>) + ; CHECK: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<4 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE16_1:%[0-9]+]]:_(<4 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE16_]](<4 x i16>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_1]](<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<8 x s16>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<8 x s16>) = G_DUPLANE16 %0, %1 - %3:_(<4 x s16>), %4:_(<4 x s16>) = G_UNMERGE_VALUES %2 + %0:_(<8 x i16>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<8 x i16>) = G_DUPLANE16 %0, %1 + %3:_(<4 x i16>), %4:_(<4 x i16>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -51,17 +51,17 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup32 - ; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64) - ; CHECK-NEXT: [[DUPLANE32_1:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) - ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_1]](<2 x s32>) + ; CHECK: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: [[DUPLANE32_1:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) + ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_1]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<4 x s32>) = G_DUPLANE32 %0, %1 - %3:_(<2 x s32>), %4:_(<2 x s32>) = G_UNMERGE_VALUES %2 + %0:_(<4 x i32>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<4 x i32>) = G_DUPLANE32 %0, %1 + %3:_(<2 x i32>), %4:_(<2 x i32>) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 @@ -73,20 +73,20 @@ legalized: true body: | bb.1.entry: ; CHECK-LABEL: name: unmerge_dup64 - ; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x s64>) = G_DUPLANE64 [[COPY]], [[C]](s64) + ; CHECK: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x i64>) = G_DUPLANE64 [[COPY]], [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x s64>), [[C1]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x i64>), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x s64>), [[C2]](i64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) - ; CHECK-NEXT: $d1 = COPY [[EVEC1]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(i64) = G_EXTRACT_VECTOR_ELT [[DUPLANE64_]](<2 x i64>), [[C2]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](i64) + ; CHECK-NEXT: $d1 = COPY [[EVEC1]](i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(s64) = G_CONSTANT i64 1 - %2:_(<2 x s64>) = G_DUPLANE64 %0, %1 - %3:_(s64), %4:_(s64) = G_UNMERGE_VALUES %2 + %0:_(<2 x i64>) = COPY $q0 + %1:_(i64) = G_CONSTANT i64 1 + %2:_(<2 x i64>) = G_DUPLANE64 %0, %1 + %3:_(i64), %4:_(i64) = G_UNMERGE_VALUES %2 $d0 = COPY %3 $d1 = COPY %4 RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir index a86691b30f44d..56c1088c3a580 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-adjust-icmp-imm.mir @@ -20,10 +20,10 @@ body: | ; LOWER-LABEL: name: slt_to_sle_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: slt_to_sle_s32 @@ -34,10 +34,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -56,10 +56,10 @@ body: | ; LOWER-LABEL: name: slt_to_sle_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: slt_to_sle_s64 @@ -70,10 +70,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -92,10 +92,10 @@ body: | ; LOWER-LABEL: name: sge_to_sgt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sge_to_sgt_s32 @@ -106,10 +106,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(sge), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -128,10 +128,10 @@ body: | ; LOWER-LABEL: name: sge_to_sgt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sge_to_sgt_s64 @@ -142,10 +142,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(sge), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -164,10 +164,10 @@ body: | ; LOWER-LABEL: name: ult_to_ule_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ule), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: ult_to_ule_s32 @@ -178,10 +178,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -200,10 +200,10 @@ body: | ; LOWER-LABEL: name: ult_to_ule_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ule), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ule), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: ult_to_ule_s64 @@ -214,10 +214,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 8, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -236,10 +236,10 @@ body: | ; LOWER-LABEL: name: uge_to_ugt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ugt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: uge_to_ugt_s32 @@ -250,10 +250,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 4097 - %cmp:_(s32) = G_ICMP intpred(uge), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 4097 + %cmp:_(i32) = G_ICMP intpred(uge), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -272,10 +272,10 @@ body: | ; LOWER-LABEL: name: uge_to_ugt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4096 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ugt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 4096 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ugt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: uge_to_ugt_s64 @@ -286,10 +286,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 9, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 4097 - %cmp:_(s32) = G_ICMP intpred(uge), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 4097 + %cmp:_(i32) = G_ICMP intpred(uge), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -309,10 +309,10 @@ body: | ; LOWER-LABEL: name: sle_to_slt_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sle_to_slt_s32 @@ -323,10 +323,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 8191 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 8191 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -345,10 +345,10 @@ body: | ; LOWER-LABEL: name: sle_to_slt_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sle_to_slt_s64 @@ -359,10 +359,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 8191 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 8191 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -381,10 +381,10 @@ body: | ; LOWER-LABEL: name: sgt_to_sge_s32 ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s32), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sge), %reg(i32), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sgt_to_sge_s32 @@ -395,10 +395,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 8191 - %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 8191 + %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -417,10 +417,10 @@ body: | ; LOWER-LABEL: name: sgt_to_sge_s64 ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8192 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sge), %reg(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 8192 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sge), %reg(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: sgt_to_sge_s64 @@ -431,10 +431,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 11, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 8191 - %cmp:_(s32) = G_ICMP intpred(sgt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 8191 + %cmp:_(i32) = G_ICMP intpred(sgt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -455,10 +455,10 @@ body: | ; LOWER-LABEL: name: no_opt_int32_min ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -2147483648 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 -2147483648 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int32_min @@ -470,10 +470,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 -2147483648 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 -2147483648 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -494,10 +494,10 @@ body: | ; LOWER-LABEL: name: no_opt_int64_min ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 -9223372036854775808 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 -9223372036854775808 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int64_min @@ -509,10 +509,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 10, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 -9223372036854775808 - %cmp:_(s32) = G_ICMP intpred(slt), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 -9223372036854775808 + %cmp:_(i32) = G_ICMP intpred(slt), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -533,10 +533,10 @@ body: | ; LOWER-LABEL: name: no_opt_int32_max ; LOWER: liveins: $w0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s32) = COPY $w0 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 2147483647 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i32) = COPY $w0 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 2147483647 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int32_max @@ -548,10 +548,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s32) = COPY $w0 - %cst:_(s32) = G_CONSTANT i32 2147483647 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s32), %cst - $w0 = COPY %cmp(s32) + %reg:_(i32) = COPY $w0 + %cst:_(i32) = G_CONSTANT i32 2147483647 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i32), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -573,10 +573,10 @@ body: | ; LOWER-LABEL: name: no_opt_int64_max ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 9223372036854775807 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 9223372036854775807 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_int64_max @@ -588,10 +588,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 12, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 9223372036854775807 - %cmp:_(s32) = G_ICMP intpred(sle), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 9223372036854775807 + %cmp:_(i32) = G_ICMP intpred(sle), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -612,10 +612,10 @@ body: | ; LOWER-LABEL: name: no_opt_zero ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg:_(s64) = COPY $x0 - ; LOWER-NEXT: %cst:_(s64) = G_CONSTANT i64 0 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg:_(i64) = COPY $x0 + ; LOWER-NEXT: %cst:_(i64) = G_CONSTANT i64 0 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: no_opt_zero @@ -626,10 +626,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 2, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg:_(s64) = COPY $x0 - %cst:_(s64) = G_CONSTANT i64 0 - %cmp:_(s32) = G_ICMP intpred(ult), %reg(s64), %cst - $w0 = COPY %cmp(s32) + %reg:_(i64) = COPY $x0 + %cst:_(i64) = G_CONSTANT i64 0 + %cmp:_(i32) = G_ICMP intpred(ult), %reg(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 ... @@ -647,12 +647,12 @@ body: | ; LOWER-LABEL: name: cmp_and_select ; LOWER: liveins: $w0, $w1 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg0:_(s32) = COPY $w0 - ; LOWER-NEXT: %reg1:_(s32) = COPY $w1 - ; LOWER-NEXT: %cst:_(s32) = G_CONSTANT i32 -1 - ; LOWER-NEXT: %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst - ; LOWER-NEXT: %select:_(s32) = G_SELECT %cmp(s32), %reg0, %reg1 - ; LOWER-NEXT: $w0 = COPY %select(s32) + ; LOWER-NEXT: %reg0:_(i32) = COPY $w0 + ; LOWER-NEXT: %reg1:_(i32) = COPY $w1 + ; LOWER-NEXT: %cst:_(i32) = G_CONSTANT i32 -1 + ; LOWER-NEXT: %cmp:_(i32) = G_ICMP intpred(sle), %reg0(i32), %cst + ; LOWER-NEXT: %select:_(i32) = G_SELECT %cmp(i32), %reg0, %reg1 + ; LOWER-NEXT: $w0 = COPY %select(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: cmp_and_select @@ -664,12 +664,12 @@ body: | ; SELECT-NEXT: %select:gpr32 = CSELWr %reg0, %reg1, 13, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %select ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg0:_(s32) = COPY $w0 - %reg1:_(s32) = COPY $w1 - %cst:_(s32) = G_CONSTANT i32 -1 - %cmp:_(s32) = G_ICMP intpred(sle), %reg0(s32), %cst - %select:_(s32) = G_SELECT %cmp, %reg0, %reg1 - $w0 = COPY %select(s32) + %reg0:_(i32) = COPY $w0 + %reg1:_(i32) = COPY $w1 + %cst:_(i32) = G_CONSTANT i32 -1 + %cmp:_(i32) = G_ICMP intpred(sle), %reg0(i32), %cst + %select:_(i32) = G_SELECT %cmp, %reg0, %reg1 + $w0 = COPY %select(i32) RET_ReallyLR implicit $w0 ... @@ -686,12 +686,12 @@ body: | ; LOWER-LABEL: name: andsxri ; LOWER: liveins: $x0 ; LOWER-NEXT: {{ $}} - ; LOWER-NEXT: %reg0:gpr(s64) = COPY $x0 - ; LOWER-NEXT: %bit:gpr(s64) = G_CONSTANT i64 8 - ; LOWER-NEXT: %and:gpr(s64) = G_AND %reg0, %bit - ; LOWER-NEXT: [[C:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 0 - ; LOWER-NEXT: %cmp:gpr(s32) = G_ICMP intpred(sge), %and(s64), [[C]] - ; LOWER-NEXT: $w0 = COPY %cmp(s32) + ; LOWER-NEXT: %reg0:gpr(i64) = COPY $x0 + ; LOWER-NEXT: %bit:gpr(i64) = G_CONSTANT i64 8 + ; LOWER-NEXT: %and:gpr(i64) = G_AND %reg0, %bit + ; LOWER-NEXT: [[C:%[0-9]+]]:gpr(i64) = G_CONSTANT i64 0 + ; LOWER-NEXT: %cmp:gpr(i32) = G_ICMP intpred(sge), %and(i64), [[C]] + ; LOWER-NEXT: $w0 = COPY %cmp(i32) ; LOWER-NEXT: RET_ReallyLR implicit $w0 ; ; SELECT-LABEL: name: andsxri @@ -702,10 +702,10 @@ body: | ; SELECT-NEXT: %cmp:gpr32 = CSINCWr $wzr, $wzr, 4, implicit $nzcv ; SELECT-NEXT: $w0 = COPY %cmp ; SELECT-NEXT: RET_ReallyLR implicit $w0 - %reg0:gpr(s64) = COPY $x0 - %bit:gpr(s64) = G_CONSTANT i64 8 - %and:gpr(s64) = G_AND %reg0, %bit - %cst:gpr(s64) = G_CONSTANT i64 -1 - %cmp:gpr(s32) = G_ICMP intpred(sgt), %and(s64), %cst - $w0 = COPY %cmp(s32) + %reg0:gpr(i64) = COPY $x0 + %bit:gpr(i64) = G_CONSTANT i64 8 + %and:gpr(i64) = G_AND %reg0, %bit + %cst:gpr(i64) = G_CONSTANT i64 -1 + %cmp:gpr(i32) = G_ICMP intpred(sgt), %and(i64), %cst + $w0 = COPY %cmp(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir index 35cc62293200b..45e7bde34661c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-ext.mir @@ -15,16 +15,16 @@ body: | ; CHECK-LABEL: name: v8s8_cst3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -38,16 +38,16 @@ body: | ; CHECK-LABEL: name: v8s8_cst5 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 5 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(13, 14, 15, 0, 1, 2, 3, 4) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(13, 14, 15, 0, 1, 2, 3, 4) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -61,16 +61,16 @@ body: | ; CHECK-LABEL: name: v16s8_cst3 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -84,16 +84,16 @@ body: | ; CHECK-LABEL: name: v16s8_cst7 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 7 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 1, 2, 3, 4, 5, 6) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -107,16 +107,16 @@ body: | ; CHECK-LABEL: name: v4s16_cst6 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s16>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<4 x s16>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<4 x i16>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<4 x i16>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %shuf:_(<4 x s16>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<4 x s16>) + ; CHECK-NEXT: %shuf:_(<4 x i16>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<4 x s16>) = COPY $d0 - %v2:_(<4 x s16>) = COPY $d1 - %shuf:_(<4 x s16>) = G_SHUFFLE_VECTOR %v1(<4 x s16>), %v2, shufflemask(3, 4, 5, 6) - $d0 = COPY %shuf(<4 x s16>) + %v1:_(<4 x i16>) = COPY $d0 + %v2:_(<4 x i16>) = COPY $d1 + %shuf:_(<4 x i16>) = G_SHUFFLE_VECTOR %v1(<4 x i16>), %v2, shufflemask(3, 4, 5, 6) + $d0 = COPY %shuf(<4 x i16>) RET_ReallyLR implicit $d0 ... --- @@ -130,16 +130,16 @@ body: | ; CHECK-LABEL: name: v4s32_cst12 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<4 x i32>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 12 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %v2:_(<4 x s32>) = COPY $q1 - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %v1(<4 x s32>), %v2, shufflemask(3, 4, 5, 6) - $q0 = COPY %shuf(<4 x s32>) + %v1:_(<4 x i32>) = COPY $q0 + %v2:_(<4 x i32>) = COPY $q1 + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %v1(<4 x i32>), %v2, shufflemask(3, 4, 5, 6) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -155,16 +155,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 3 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v1, %v2, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v1, %v2, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(3, -1, -1, 6, 7, 8, 9, 10) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(3, -1, -1, 6, 7, 8, 9, 10) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -180,16 +180,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: %v2:_(<8 x s8>) = COPY $d1 + ; CHECK-NEXT: %v1:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: %v2:_(<8 x i8>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 - ; CHECK-NEXT: %shuf:_(<8 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $d0 = COPY %shuf(<8 x s8>) + ; CHECK-NEXT: %shuf:_(<8 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $d0 = COPY %shuf(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %v1:_(<8 x s8>) = COPY $d0 - %v2:_(<8 x s8>) = COPY $d1 - %shuf:_(<8 x s8>) = G_SHUFFLE_VECTOR %v1(<8 x s8>), %v2, shufflemask(-1, -1, -1, -1, 2, 3, 4, 5) - $d0 = COPY %shuf(<8 x s8>) + %v1:_(<8 x i8>) = COPY $d0 + %v2:_(<8 x i8>) = COPY $d1 + %shuf:_(<8 x i8>) = G_SHUFFLE_VECTOR %v1(<8 x i8>), %v2, shufflemask(-1, -1, -1, -1, 2, 3, 4, 5) + $d0 = COPY %shuf(<8 x i8>) RET_ReallyLR implicit $d0 ... --- @@ -205,16 +205,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_3 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<16 x s8>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<16 x i8>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 7 - ; CHECK-NEXT: %shuf:_(<16 x s8>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<16 x s8>) + ; CHECK-NEXT: %shuf:_(<16 x i8>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %v2:_(<16 x s8>) = COPY $q1 - %shuf:_(<16 x s8>) = G_SHUFFLE_VECTOR %v1(<16 x s8>), %v2, shufflemask(23, 24, 25, 26, -1, -1, 29, 30, 31, 0, 1, 2, 3, 4, -1, 6) - $q0 = COPY %shuf(<16 x s8>) + %v1:_(<16 x i8>) = COPY $q0 + %v2:_(<16 x i8>) = COPY $q1 + %shuf:_(<16 x i8>) = G_SHUFFLE_VECTOR %v1(<16 x i8>), %v2, shufflemask(23, 24, 25, 26, -1, -1, 29, 30, 31, 0, 1, 2, 3, 4, -1, 6) + $q0 = COPY %shuf(<16 x i8>) RET_ReallyLR implicit $q0 ... --- @@ -230,16 +230,16 @@ body: | ; CHECK-LABEL: name: undef_elts_should_match_4 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: %v2:_(<8 x s16>) = COPY $q1 + ; CHECK-NEXT: %v1:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: %v2:_(<8 x i16>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 10 - ; CHECK-NEXT: %shuf:_(<8 x s16>) = G_EXT %v2, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<8 x s16>) + ; CHECK-NEXT: %shuf:_(<8 x i16>) = G_EXT %v2, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %v2:_(<8 x s16>) = COPY $q1 - %shuf:_(<8 x s16>) = G_SHUFFLE_VECTOR %v1(<8 x s16>), %v2, shufflemask(-1, -1, -1, -1, 1, 2, 3, 4) - $q0 = COPY %shuf(<8 x s16>) + %v1:_(<8 x i16>) = COPY $q0 + %v2:_(<8 x i16>) = COPY $q1 + %shuf:_(<8 x i16>) = G_SHUFFLE_VECTOR %v1(<8 x i16>), %v2, shufflemask(-1, -1, -1, -1, 1, 2, 3, 4) + $q0 = COPY %shuf(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -254,15 +254,15 @@ body: | ; CHECK-LABEL: name: all_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<8 x i16>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<8 x s16>) = G_DUPLANE16 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<8 x s16>) + ; CHECK-NEXT: %shuf:_(<8 x i16>) = G_DUPLANE16 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %v2:_(<8 x s16>) = COPY $q1 - %shuf:_(<8 x s16>) = G_SHUFFLE_VECTOR %v1(<8 x s16>), %v2, shufflemask(-1, -1, -1, -1, -1, -1, -1, -1) - $q0 = COPY %shuf(<8 x s16>) + %v1:_(<8 x i16>) = COPY $q0 + %v2:_(<8 x i16>) = COPY $q1 + %shuf:_(<8 x i16>) = G_SHUFFLE_VECTOR %v1(<8 x i16>), %v2, shufflemask(-1, -1, -1, -1, -1, -1, -1, -1) + $q0 = COPY %shuf(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -276,15 +276,15 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_EXT %v1, %v1, [[C]](i32) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_EXT %v1, %v1, [[C]](i32) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(1, 0) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(1, 0) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -298,15 +298,15 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext_all_undef ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_DUPLANE64 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_DUPLANE64 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(undef, undef) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(undef, undef) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... --- @@ -320,14 +320,14 @@ body: | ; CHECK-LABEL: name: v2s64_singleton_ext_same ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: %v1:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s64>) = G_DUPLANE64 %v1, [[C]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<2 x s64>) + ; CHECK-NEXT: %shuf:_(<2 x i64>) = G_DUPLANE64 %v1, [[C]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<2 x s64>) = COPY $q0 - %v2:_(<2 x s64>) = G_IMPLICIT_DEF - %shuf:_(<2 x s64>) = G_SHUFFLE_VECTOR %v1(<2 x s64>), %v2, shufflemask(1, 1) - $q0 = COPY %shuf(<2 x s64>) + %v1:_(<2 x i64>) = COPY $q0 + %v2:_(<2 x i64>) = G_IMPLICIT_DEF + %shuf:_(<2 x i64>) = G_SHUFFLE_VECTOR %v1(<2 x i64>), %v2, shufflemask(1, 1) + $q0 = COPY %shuf(<2 x i64>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir index bdd633076d49c..74e940266776c 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-rev.mir @@ -16,14 +16,14 @@ body: | ; CHECK-LABEL: name: rev64_mask_1_0 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[REV64_:%[0-9]+]]:_(<2 x s32>) = G_REV64 [[COPY]] - ; CHECK-NEXT: $d0 = COPY [[REV64_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[REV64_:%[0-9]+]]:_(<2 x i32>) = G_REV64 [[COPY]] + ; CHECK-NEXT: $d0 = COPY [[REV64_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 0) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -38,17 +38,17 @@ body: | ; CHECK-LABEL: name: rev64_mask_1_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[COPY]](<2 x s32>), [[DEF]](<2 x s32>) - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x i32>) = G_CONCAT_VECTORS [[COPY]](<2 x i32>), [[DEF]](<2 x i32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, undef) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, undef) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -74,13 +74,13 @@ body: | ; CHECK-LABEL: name: no_rev64_mask_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir index 76d4d29102cc1..65d8d96dd2e1b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-sextinreg.mir @@ -10,15 +10,15 @@ body: | ; CHECK-LABEL: name: v4s32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 16 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[C]](s32) - ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(<4 x s32>) = G_SHL %v1, [[DUP]](<4 x s32>) - ; CHECK-NEXT: %sext:_(<4 x s32>) = G_VASHR [[SHL]], 16 - ; CHECK-NEXT: $q0 = COPY %sext(<4 x s32>) + ; CHECK-NEXT: %v1:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 16 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[C]](i32) + ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(<4 x i32>) = G_SHL %v1, [[DUP]](<4 x i32>) + ; CHECK-NEXT: %sext:_(<4 x i32>) = G_VASHR [[SHL]], 16 + ; CHECK-NEXT: $q0 = COPY %sext(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %sext:_(<4 x s32>) = G_SEXT_INREG %v1, 16 + %v1:_(<4 x i32>) = COPY $q0 + %sext:_(<4 x i32>) = G_SEXT_INREG %v1, 16 $q0 = COPY %sext RET_ReallyLR implicit $q0 ... @@ -31,12 +31,12 @@ body: | ; CHECK-LABEL: name: scalar_no_lower ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(s64) = COPY $x0 - ; CHECK-NEXT: %sext:_(s64) = G_SEXT_INREG %v1, 16 - ; CHECK-NEXT: $x0 = COPY %sext(s64) + ; CHECK-NEXT: %v1:_(i64) = COPY $x0 + ; CHECK-NEXT: %sext:_(i64) = G_SEXT_INREG %v1, 16 + ; CHECK-NEXT: $x0 = COPY %sext(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %v1:_(s64) = COPY $x0 - %sext:_(s64) = G_SEXT_INREG %v1, 16 + %v1:_(i64) = COPY $x0 + %sext:_(i64) = G_SEXT_INREG %v1, 16 $x0 = COPY %sext RET_ReallyLR implicit $x0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir index 31d7a3f23a127..643ad10a2ec6b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuf-to-ins.mir @@ -22,17 +22,17 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_0 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 0) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(0, 0) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -52,17 +52,17 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(1, 1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -82,18 +82,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_left_3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(0, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(0, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 @@ -114,18 +114,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_right_3 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(1, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(1, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -145,18 +145,18 @@ body: | ; CHECK-LABEL: name: v2s32_match_right_2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 0) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 0) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -174,15 +174,15 @@ body: | ; CHECK-LABEL: name: dont_combine_too_many_matches_right ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 3) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 3) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 3) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -203,18 +203,18 @@ body: | ; CHECK-LABEL: name: tiebreaker ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, 1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, 1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -234,18 +234,18 @@ body: | ; CHECK-LABEL: name: tiebreaker_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(2, -1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(2, -1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -265,18 +265,18 @@ body: | ; CHECK-LABEL: name: match_left_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: %right:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: %left:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: %right:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %right(<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %right(<2 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<2 x s32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $d0 = COPY %shuf(<2 x s32>) + ; CHECK-NEXT: %shuf:_(<2 x i32>) = G_INSERT_VECTOR_ELT %left, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $d0 = COPY %shuf(<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %left:_(<2 x s32>) = COPY $d0 - %right:_(<2 x s32>) = COPY $d1 - %shuf:_(<2 x s32>) = G_SHUFFLE_VECTOR %left(<2 x s32>), %right, shufflemask(3, -1) - $d0 = COPY %shuf(<2 x s32>) + %left:_(<2 x i32>) = COPY $d0 + %right:_(<2 x i32>) = COPY $d1 + %shuf:_(<2 x i32>) = G_SHUFFLE_VECTOR %left(<2 x i32>), %right, shufflemask(3, -1) + $d0 = COPY %shuf(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -295,16 +295,16 @@ body: | ; CHECK-LABEL: name: match_right_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %left:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %right:_(<4 x s32>) = COPY $q1 + ; CHECK-NEXT: %left:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %right:_(<4 x i32>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT %left(<4 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(i32) = G_EXTRACT_VECTOR_ELT %left(<4 x i32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](s32), [[C1]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_INSERT_VECTOR_ELT %right, [[EVEC]](i32), [[C1]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %left:_(<4 x s32>) = COPY $q0 - %right:_(<4 x s32>) = COPY $q1 - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %left(<4 x s32>), %right, shufflemask(4, -1, -1, 2) - $q0 = COPY %shuf(<4 x s32>) + %left:_(<4 x i32>) = COPY $q0 + %right:_(<4 x i32>) = COPY $q1 + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %left(<4 x i32>), %right, shufflemask(4, -1, -1, 2) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir index 5297ecd7019bb..a94f2ac13f3de 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-duplane.mir @@ -14,10 +14,10 @@ body: | ; CHECK-LABEL: name: duplane64 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x s64>) = G_DUPLANE64 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE64_]](<2 x s64>) + ; CHECK-NEXT: [[DUPLANE64_:%[0-9]+]]:_(<2 x i64>) = G_DUPLANE64 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE64_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane64 @@ -27,10 +27,10 @@ body: | ; SELECTED-NEXT: [[DUPv2i64lane:%[0-9]+]]:fpr128 = DUPv2i64lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv2i64lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %1:_(<2 x i64>) = COPY $q0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -46,10 +46,10 @@ body: | ; CHECK-LABEL: name: duplane32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<4 x s32>) = G_DUPLANE32 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE32_]](<4 x s32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<4 x i32>) = G_DUPLANE32 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE32_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane32 @@ -59,10 +59,10 @@ body: | ; SELECTED-NEXT: [[DUPv4i32lane:%[0-9]+]]:fpr128 = DUPv4i32lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv4i32lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<4 x s32>) = COPY $q0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %1:_(<4 x i32>) = COPY $q0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -78,10 +78,10 @@ body: | ; CHECK-LABEL: name: duplane16 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<8 x s16>) = G_DUPLANE16 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE16_]](<8 x s16>) + ; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<8 x i16>) = G_DUPLANE16 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE16_]](<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane16 @@ -91,10 +91,10 @@ body: | ; SELECTED-NEXT: [[DUPv8i16lane:%[0-9]+]]:fpr128 = DUPv8i16lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv8i16lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<8 x s16>) = COPY $q0 - %2:_(<8 x s16>) = G_IMPLICIT_DEF - %4:_(<8 x s16>) = G_SHUFFLE_VECTOR %1(<8 x s16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) - $q0 = COPY %4(<8 x s16>) + %1:_(<8 x i16>) = COPY $q0 + %2:_(<8 x i16>) = G_IMPLICIT_DEF + %4:_(<8 x i16>) = G_SHUFFLE_VECTOR %1(<8 x i16>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) + $q0 = COPY %4(<8 x i16>) RET_ReallyLR implicit $q0 ... @@ -110,10 +110,10 @@ body: | ; CHECK-LABEL: name: duplane8 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<16 x s8>) = G_DUPLANE8 [[COPY]], [[C]](i64) - ; CHECK-NEXT: $q0 = COPY [[DUPLANE8_]](<16 x s8>) + ; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<16 x i8>) = G_DUPLANE8 [[COPY]], [[C]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUPLANE8_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 ; ; SELECTED-LABEL: name: duplane8 @@ -123,10 +123,10 @@ body: | ; SELECTED-NEXT: [[DUPv16i8lane:%[0-9]+]]:fpr128 = DUPv16i8lane [[COPY]], 0 ; SELECTED-NEXT: $q0 = COPY [[DUPv16i8lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $q0 - %1:_(<16 x s8>) = COPY $q0 - %2:_(<16 x s8>) = G_IMPLICIT_DEF - %4:_(<16 x s8>) = G_SHUFFLE_VECTOR %1(<16 x s8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - $q0 = COPY %4(<16 x s8>) + %1:_(<16 x i8>) = COPY $q0 + %2:_(<16 x i8>) = G_IMPLICIT_DEF + %4:_(<16 x i8>) = G_SHUFFLE_VECTOR %1(<16 x i8>), %2, shufflemask(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + $q0 = COPY %4(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -148,13 +148,13 @@ body: | ; CHECK-LABEL: name: v2s32_duplane32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[COPY1]](<2 x s32>), [[DEF]](<2 x s32>) - ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) - ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>) + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<4 x i32>) = G_CONCAT_VECTORS [[COPY1]](<2 x i32>), [[DEF]](<2 x i32>) + ; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x i32>) = G_DUPLANE32 [[CONCAT_VECTORS]], [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 ; ; SELECTED-LABEL: name: v2s32_duplane32 @@ -166,11 +166,11 @@ body: | ; SELECTED-NEXT: [[DUPv2i32lane:%[0-9]+]]:fpr64 = DUPv2i32lane [[INSERT_SUBREG]], 0 ; SELECTED-NEXT: $d0 = COPY [[DUPv2i32lane]] ; SELECTED-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %3(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %3(<2 x i32>) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir index 650a4fb8a8232..8e20fff540d4e 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-shuffle-splat.mir @@ -13,16 +13,16 @@ body: | ; CHECK-LABEL: name: splat_4xi32 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $w0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $w0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -38,16 +38,16 @@ body: | ; CHECK-LABEL: name: splat_2xi64 ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -63,16 +63,16 @@ body: | ; CHECK-LABEL: name: splat_2xi32 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(s32) = COPY $w0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %4(<2 x s32>) + %0:_(i32) = COPY $w0 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %4(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -88,16 +88,16 @@ body: | ; CHECK-LABEL: name: splat_4xf32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, 0, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, 0, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -113,16 +113,16 @@ body: | ; CHECK-LABEL: name: splat_2xf64 ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $d0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $d0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $d0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -138,16 +138,16 @@ body: | ; CHECK-LABEL: name: splat_2xf32 ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $d0 = COPY [[DUP]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(s32) = COPY $s0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<2 x s32>) = G_SHUFFLE_VECTOR %1(<2 x s32>), %2, shufflemask(0, 0) - $d0 = COPY %4(<2 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<2 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<2 x i32>) = G_SHUFFLE_VECTOR %1(<2 x i32>), %2, shufflemask(0, 0) + $d0 = COPY %4(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -165,18 +165,18 @@ body: | ; CHECK-LABEL: name: splat_2xf64_copies ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $d0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $d0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %6:_(<2 x s64>) = COPY %2 - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %6, %0(s64), %3(s64) - %7:_(<2 x s64>) = COPY %1 - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %7(<2 x s64>), %2, shufflemask(0, 0) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $d0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %6:_(<2 x i64>) = COPY %2 + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %6, %0(i64), %3(i64) + %7:_(<2 x i64>) = COPY %1 + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %7(<2 x i64>), %2, shufflemask(0, 0) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -192,19 +192,19 @@ body: | ; CHECK-LABEL: name: not_all_zeros ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<2 x s64>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s64), [[C]](s64) - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY [[IVEC]](<2 x s64>) - ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x i64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<2 x i64>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](i64), [[C]](i64) + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY [[IVEC]](<2 x i64>) + ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(0, 1) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(0, 1) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -222,16 +222,16 @@ body: | ; CHECK-LABEL: name: all_undef ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x s64>) = G_DUP [[COPY]](s64) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<2 x i64>) = G_DUP [[COPY]](i64) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s64) = COPY $x0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_INSERT_VECTOR_ELT %2, %0(s64), %3(s64) - %4:_(<2 x s64>) = G_SHUFFLE_VECTOR %1(<2 x s64>), %2, shufflemask(-1, -1) - $q0 = COPY %4(<2 x s64>) + %0:_(i64) = COPY $x0 + %2:_(<2 x i64>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x i64>) = G_INSERT_VECTOR_ELT %2, %0(i64), %3(i64) + %4:_(<2 x i64>) = G_SHUFFLE_VECTOR %1(<2 x i64>), %2, shufflemask(-1, -1) + $q0 = COPY %4(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -248,16 +248,16 @@ body: | ; CHECK-LABEL: name: one_undef ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[COPY]](s32) - ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[COPY]](i32) + ; CHECK-NEXT: $q0 = COPY [[DUP]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(0, -1, 0, 0) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(0, -1, 0, 0) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -272,19 +272,19 @@ body: | ; CHECK-LABEL: name: not_all_zeros_with_undefs ; CHECK: liveins: $s0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $s0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s32), [[C]](s64) - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[IVEC]](<4 x s32>), [[DEF]], shufflemask(undef, 0, 0, 3) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $s0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], [[COPY]](i32), [[C]](i64) + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[IVEC]](<4 x i32>), [[DEF]], shufflemask(undef, 0, 0, 3) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(s32) = COPY $s0 - %2:_(<4 x s32>) = G_IMPLICIT_DEF - %3:_(s64) = G_CONSTANT i64 0 - %1:_(<4 x s32>) = G_INSERT_VECTOR_ELT %2, %0(s32), %3(s64) - %4:_(<4 x s32>) = G_SHUFFLE_VECTOR %1(<4 x s32>), %2, shufflemask(-1, 0, 0, 3) - $q0 = COPY %4(<4 x s32>) + %0:_(i32) = COPY $s0 + %2:_(<4 x i32>) = G_IMPLICIT_DEF + %3:_(i64) = G_CONSTANT i64 0 + %1:_(<4 x i32>) = G_INSERT_VECTOR_ELT %2, %0(i32), %3(i64) + %4:_(<4 x i32>) = G_SHUFFLE_VECTOR %1(<4 x i32>), %2, shufflemask(-1, 0, 0, 3) + $q0 = COPY %4(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -299,16 +299,16 @@ body: | ; CHECK-LABEL: name: splat_4xi16 ; CHECK: liveins: $h0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s16) = COPY $h0 - ; CHECK-NEXT: %splat:_(<4 x s16>) = G_DUP %copy(s16) - ; CHECK-NEXT: $d0 = COPY %splat(<4 x s16>) + ; CHECK-NEXT: %copy:_(i16) = COPY $h0 + ; CHECK-NEXT: %splat:_(<4 x i16>) = G_DUP %copy(i16) + ; CHECK-NEXT: $d0 = COPY %splat(<4 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:_(s16) = COPY $h0 - %undef:_(<4 x s16>) = G_IMPLICIT_DEF - %cst:_(s64) = G_CONSTANT i64 0 - %ins:_(<4 x s16>) = G_INSERT_VECTOR_ELT %undef, %copy(s16), %cst(s64) - %splat:_(<4 x s16>) = G_SHUFFLE_VECTOR %ins(<4 x s16>), %undef, shufflemask(0, 0, 0, 0) - $d0 = COPY %splat(<4 x s16>) + %copy:_(i16) = COPY $h0 + %undef:_(<4 x i16>) = G_IMPLICIT_DEF + %cst:_(i64) = G_CONSTANT i64 0 + %ins:_(<4 x i16>) = G_INSERT_VECTOR_ELT %undef, %copy(i16), %cst(i64) + %splat:_(<4 x i16>) = G_SHUFFLE_VECTOR %ins(<4 x i16>), %undef, shufflemask(0, 0, 0, 0) + $d0 = COPY %splat(<4 x i16>) RET_ReallyLR implicit $d0 ... @@ -323,16 +323,16 @@ body: | ; CHECK-LABEL: name: splat_8xi8 ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %copy:_(s32) = COPY $w0 - ; CHECK-NEXT: %splat:_(<8 x s8>) = G_DUP %copy(s32) - ; CHECK-NEXT: $d0 = COPY %splat(<8 x s8>) + ; CHECK-NEXT: %copy:_(i32) = COPY $w0 + ; CHECK-NEXT: %splat:_(<8 x i8>) = G_DUP %copy(i32) + ; CHECK-NEXT: $d0 = COPY %splat(<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %copy:_(s32) = COPY $w0 - %undef:_(<8 x s8>) = G_IMPLICIT_DEF - %cst:_(s64) = G_CONSTANT i64 0 - %ins:_(<8 x s8>) = G_INSERT_VECTOR_ELT %undef, %copy(s32), %cst(s64) - %splat:_(<8 x s8>) = G_SHUFFLE_VECTOR %ins(<8 x s8>), %undef, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) - $d0 = COPY %splat(<8 x s8>) + %copy:_(i32) = COPY $w0 + %undef:_(<8 x i8>) = G_IMPLICIT_DEF + %cst:_(i64) = G_CONSTANT i64 0 + %ins:_(<8 x i8>) = G_INSERT_VECTOR_ELT %undef, %copy(i32), %cst(i64) + %splat:_(<8 x i8>) = G_SHUFFLE_VECTOR %ins(<8 x i8>), %undef, shufflemask(0, 0, 0, 0, 0, 0, 0, 0) + $d0 = COPY %splat(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -349,32 +349,32 @@ body: | ; CHECK-LABEL: name: build_vector ; CHECK: liveins: $w0, $w1, $w2, $w3 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %lane:_(s32) = COPY $w0 - ; CHECK-NEXT: %b:_(s32) = COPY $w1 - ; CHECK-NEXT: %c:_(s32) = COPY $w2 - ; CHECK-NEXT: %d:_(s32) = COPY $w3 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %lane:_(i32) = COPY $w0 + ; CHECK-NEXT: %b:_(i32) = COPY $w1 + ; CHECK-NEXT: %c:_(i32) = COPY $w2 + ; CHECK-NEXT: %d:_(i32) = COPY $w3 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane(s32), [[C]](i64) + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane(i32), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(s32), [[C1]](i64) + ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(i32), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(s32), [[C2]](i64) + ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(i32), [[C2]](i64) ; CHECK-NEXT: [[C3:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(s32), [[C3]](i64) - ; CHECK-NEXT: %buildvec:_(<4 x s32>) = COPY [[IVEC3]](<4 x s32>) + ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(i32), [[C3]](i64) + ; CHECK-NEXT: %buildvec:_(<4 x i32>) = COPY [[IVEC3]](<4 x i32>) ; CHECK-NEXT: [[C4:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_DUPLANE32 %buildvec, [[C4]](i64) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_DUPLANE32 %buildvec, [[C4]](i64) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lane:_(s32) = COPY $w0 - %b:_(s32) = COPY $w1 - %c:_(s32) = COPY $w2 - %d:_(s32) = COPY $w3 - %undef:_(<4 x s32>) = G_IMPLICIT_DEF - %buildvec:_(<4 x s32>) = G_BUILD_VECTOR %lane, %b, %c, %d - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec(<4 x s32>), %undef, shufflemask(0, 0, 0, 0) - $q0 = COPY %shuf(<4 x s32>) + %lane:_(i32) = COPY $w0 + %b:_(i32) = COPY $w1 + %c:_(i32) = COPY $w2 + %d:_(i32) = COPY $w3 + %undef:_(<4 x i32>) = G_IMPLICIT_DEF + %buildvec:_(<4 x i32>) = G_BUILD_VECTOR %lane, %b, %c, %d + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec(<4 x i32>), %undef, shufflemask(0, 0, 0, 0) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -391,41 +391,41 @@ body: | ; CHECK-LABEL: name: build_vector_rhs ; CHECK: liveins: $w0, $w1, $w2, $w3, $w4 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %lane_0:_(s32) = COPY $w0 - ; CHECK-NEXT: %lane_1:_(s32) = COPY $w1 - ; CHECK-NEXT: %b:_(s32) = COPY $w2 - ; CHECK-NEXT: %c:_(s32) = COPY $w3 - ; CHECK-NEXT: %d:_(s32) = COPY $w4 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %lane_0:_(i32) = COPY $w0 + ; CHECK-NEXT: %lane_1:_(i32) = COPY $w1 + ; CHECK-NEXT: %b:_(i32) = COPY $w2 + ; CHECK-NEXT: %c:_(i32) = COPY $w3 + ; CHECK-NEXT: %d:_(i32) = COPY $w4 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane_0(s32), [[C]](i64) + ; CHECK-NEXT: [[IVEC:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF]], %lane_0(i32), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(s32), [[C1]](i64) + ; CHECK-NEXT: [[IVEC1:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC]], %b(i32), [[C1]](i64) ; CHECK-NEXT: [[C2:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(s32), [[C2]](i64) + ; CHECK-NEXT: [[IVEC2:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC1]], %c(i32), [[C2]](i64) ; CHECK-NEXT: [[C3:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(s32), [[C3]](i64) - ; CHECK-NEXT: %buildvec0:_(<4 x s32>) = COPY [[IVEC3]](<4 x s32>) - ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[IVEC3:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC2]], %d(i32), [[C3]](i64) + ; CHECK-NEXT: %buildvec0:_(<4 x i32>) = COPY [[IVEC3]](<4 x i32>) + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(<4 x i32>) = G_IMPLICIT_DEF ; CHECK-NEXT: [[C4:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[IVEC4:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[DEF1]], %lane_1(s32), [[C4]](i64) + ; CHECK-NEXT: [[IVEC4:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[DEF1]], %lane_1(i32), [[C4]](i64) ; CHECK-NEXT: [[C5:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[IVEC5:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC4]], %b(s32), [[C5]](i64) + ; CHECK-NEXT: [[IVEC5:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC4]], %b(i32), [[C5]](i64) ; CHECK-NEXT: [[C6:%[0-9]+]]:_(i64) = G_CONSTANT i64 2 - ; CHECK-NEXT: [[IVEC6:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC5]], %c(s32), [[C6]](i64) + ; CHECK-NEXT: [[IVEC6:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC5]], %c(i32), [[C6]](i64) ; CHECK-NEXT: [[C7:%[0-9]+]]:_(i64) = G_CONSTANT i64 3 - ; CHECK-NEXT: [[IVEC7:%[0-9]+]]:_(<4 x s32>) = G_INSERT_VECTOR_ELT [[IVEC6]], %d(s32), [[C7]](i64) - ; CHECK-NEXT: %buildvec1:_(<4 x s32>) = COPY [[IVEC7]](<4 x s32>) - ; CHECK-NEXT: %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x s32>), %buildvec1, shufflemask(4, 4, 4, 4) - ; CHECK-NEXT: $q0 = COPY %shuf(<4 x s32>) + ; CHECK-NEXT: [[IVEC7:%[0-9]+]]:_(<4 x i32>) = G_INSERT_VECTOR_ELT [[IVEC6]], %d(i32), [[C7]](i64) + ; CHECK-NEXT: %buildvec1:_(<4 x i32>) = COPY [[IVEC7]](<4 x i32>) + ; CHECK-NEXT: %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x i32>), %buildvec1, shufflemask(4, 4, 4, 4) + ; CHECK-NEXT: $q0 = COPY %shuf(<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %lane_0:_(s32) = COPY $w0 - %lane_1:_(s32) = COPY $w1 - %b:_(s32) = COPY $w2 - %c:_(s32) = COPY $w3 - %d:_(s32) = COPY $w4 - %buildvec0:_(<4 x s32>) = G_BUILD_VECTOR %lane_0(s32), %b(s32), %c(s32), %d(s32) - %buildvec1:_(<4 x s32>) = G_BUILD_VECTOR %lane_1(s32), %b(s32), %c(s32), %d(s32) - %shuf:_(<4 x s32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x s32>), %buildvec1, shufflemask(4, 4, 4, 4) - $q0 = COPY %shuf(<4 x s32>) + %lane_0:_(i32) = COPY $w0 + %lane_1:_(i32) = COPY $w1 + %b:_(i32) = COPY $w2 + %c:_(i32) = COPY $w3 + %d:_(i32) = COPY $w4 + %buildvec0:_(<4 x i32>) = G_BUILD_VECTOR %lane_0(i32), %b(i32), %c(i32), %d(i32) + %buildvec1:_(<4 x i32>) = G_BUILD_VECTOR %lane_1(i32), %b(i32), %c(i32), %d(i32) + %shuf:_(<4 x i32>) = G_SHUFFLE_VECTOR %buildvec0(<4 x i32>), %buildvec1, shufflemask(4, 4, 4, 4) + $q0 = COPY %shuf(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir index cfafc68cc0073..dc73efe3f8204 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-trn.mir @@ -17,15 +17,15 @@ body: | ; CHECK-LABEL: name: trn1_v8s8 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(0, 8, 2, 10, 4, 12, 6, 14) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(0, 8, 2, 10, 4, 12, 6, 14) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $q0 ... @@ -40,15 +40,15 @@ body: | ; CHECK-LABEL: name: trn2_v8s8 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(1, 9, 3, 11, 5, 13, 7, 15) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(1, 9, 3, 11, 5, 13, 7, 15) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $q0 ... @@ -63,15 +63,15 @@ body: | ; CHECK-LABEL: name: trn1_v16s8 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $q1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<16 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<16 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x i8>) = COPY $q1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<16 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(<16 x s8>) = COPY $q1 - %2:_(<16 x s8>) = G_SHUFFLE_VECTOR %0(<16 x s8>), %1, shufflemask(0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30) - $q0 = COPY %2(<16 x s8>) + %0:_(<16 x i8>) = COPY $q0 + %1:_(<16 x i8>) = COPY $q1 + %2:_(<16 x i8>) = G_SHUFFLE_VECTOR %0(<16 x i8>), %1, shufflemask(0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -86,15 +86,15 @@ body: | ; CHECK-LABEL: name: trn2_v16s8 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x s8>) = COPY $q1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<16 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<16 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<16 x i8>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<16 x i8>) = COPY $q1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<16 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<16 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<16 x s8>) = COPY $q0 - %1:_(<16 x s8>) = COPY $q1 - %2:_(<16 x s8>) = G_SHUFFLE_VECTOR %0(<16 x s8>), %1, shufflemask(1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31) - $q0 = COPY %2(<16 x s8>) + %0:_(<16 x i8>) = COPY $q0 + %1:_(<16 x i8>) = COPY $q1 + %2:_(<16 x i8>) = G_SHUFFLE_VECTOR %0(<16 x i8>), %1, shufflemask(1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31) + $q0 = COPY %2(<16 x i8>) RET_ReallyLR implicit $q0 ... @@ -109,15 +109,15 @@ body: | ; CHECK-LABEL: name: trn1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<4 x s32>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<4 x i32>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 4, 2, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 4, 2, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -132,15 +132,15 @@ body: | ; CHECK-LABEL: name: trn2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<4 x s32>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<4 x i32>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[TRN2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 5, 3, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 5, 3, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -156,15 +156,15 @@ body: | ; CHECK-LABEL: name: redundant_with_zip1 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, 2) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(0, 2) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -180,15 +180,15 @@ body: | ; CHECK-LABEL: name: redundant_with_zip2 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -204,15 +204,15 @@ body: | ; CHECK-LABEL: name: trn1_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x s8>) = G_TRN1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN1_:%[0-9]+]]:_(<8 x i8>) = G_TRN1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN1_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(0, 8, -1, -1, 4, 12, 6, 14) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(0, 8, -1, -1, 4, 12, 6, 14) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 ... @@ -228,13 +228,13 @@ body: | ; CHECK-LABEL: name: trn2_undef ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s8>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s8>) = COPY $d1 - ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x s8>) = G_TRN2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x s8>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i8>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x i8>) = COPY $d1 + ; CHECK-NEXT: [[TRN2_:%[0-9]+]]:_(<8 x i8>) = G_TRN2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[TRN2_]](<8 x i8>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<8 x s8>) = COPY $d0 - %1:_(<8 x s8>) = COPY $d1 - %2:_(<8 x s8>) = G_SHUFFLE_VECTOR %0(<8 x s8>), %1, shufflemask(1, -1, 3, 11, 5, 13, -1, -1) - $d0 = COPY %2(<8 x s8>) + %0:_(<8 x i8>) = COPY $d0 + %1:_(<8 x i8>) = COPY $d1 + %2:_(<8 x i8>) = G_SHUFFLE_VECTOR %0(<8 x i8>), %1, shufflemask(1, -1, 3, 11, 5, 13, -1, -1) + $d0 = COPY %2(<8 x i8>) RET_ReallyLR implicit $d0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir index 28b55a69d3c9b..5fd4fb2fa10b7 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-truncstore.mir @@ -11,12 +11,12 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(s32) = COPY $w1 - ; CHECK-NEXT: G_STORE %val(s32), %ptr(p0) :: (store (s8)) + ; CHECK-NEXT: %val:_(i32) = COPY $w1 + ; CHECK-NEXT: G_STORE %val(i32), %ptr(p0) :: (store (i8)) %ptr:_(p0) = COPY $x0 - %val:_(s32) = COPY $w1 - %trunc:_(s8) = G_TRUNC %val - G_STORE %trunc(s8), %ptr(p0) :: (store (s8)) + %val:_(i32) = COPY $w1 + %trunc:_(i8) = G_TRUNC %val + G_STORE %trunc(i8), %ptr(p0) :: (store (i8)) ... --- name: truncstore_vector @@ -28,13 +28,13 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %trunc:_(<4 x s8>) = G_TRUNC %val(<4 x s32>) - ; CHECK-NEXT: G_STORE %trunc(<4 x s8>), %ptr(p0) :: (store (<4 x s8>)) + ; CHECK-NEXT: %val:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: %trunc:_(<4 x i8>) = G_TRUNC %val(<4 x i32>) + ; CHECK-NEXT: G_STORE %trunc(<4 x i8>), %ptr(p0) :: (store (<4 x i8>)) %ptr:_(p0) = COPY $x0 - %val:_(<4 x s32>) = COPY $q0 - %trunc:_(<4 x s8>) = G_TRUNC %val - G_STORE %trunc(<4 x s8>), %ptr(p0) :: (store (<4 x s8>)) + %val:_(<4 x i32>) = COPY $q0 + %trunc:_(<4 x i8>) = G_TRUNC %val + G_STORE %trunc(<4 x i8>), %ptr(p0) :: (store (<4 x i8>)) ... --- name: truncstore_too_large @@ -46,11 +46,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: %ptr:_(p0) = COPY $x0 - ; CHECK-NEXT: %val:_(s128) = COPY $q0 - ; CHECK-NEXT: %trunc:_(s32) = G_TRUNC %val(s128) - ; CHECK-NEXT: G_STORE %trunc(s32), %ptr(p0) :: (store (s32)) + ; CHECK-NEXT: %val:_(i128) = COPY $q0 + ; CHECK-NEXT: %trunc:_(i32) = G_TRUNC %val(i128) + ; CHECK-NEXT: G_STORE %trunc(i32), %ptr(p0) :: (store (i32)) %ptr:_(p0) = COPY $x0 - %val:_(s128) = COPY $q0 - %trunc:_(s32) = G_TRUNC %val - G_STORE %trunc(s32), %ptr(p0) :: (store (s32)) + %val:_(i128) = COPY $q0 + %trunc:_(i32) = G_TRUNC %val + G_STORE %trunc(i32), %ptr(p0) :: (store (i32)) ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir index 52ef2d3578b33..24cdd6e82096b 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir @@ -10,17 +10,17 @@ body: | ; CHECK-LABEL: name: v4s32 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %v1(<4 x s32>), 2 - ; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>) + ; CHECK-NEXT: %v1:_(<4 x f32>) = COPY $q0 + ; CHECK-NEXT: %unmerge:_(<2 x f32>) = G_EXTRACT_SUBVECTOR %v1(<4 x f32>), 2 + ; CHECK-NEXT: %fpext:_(<2 x f64>) = G_FPEXT %unmerge(<2 x f32>) + ; CHECK-NEXT: $q0 = COPY %fpext(<2 x f64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<4 x s32>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<2 x s32>), %unused:_(<2 x s32>) = G_UNMERGE_VALUES %ext:_(<4 x s32>) - %fpext:_(<2 x s64>) = G_FPEXT %unmerge:_(<2 x s32>) + %v1:_(<4 x f32>) = COPY $q0 + %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<4 x f32>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<2 x f32>), %unused:_(<2 x f32>) = G_UNMERGE_VALUES %ext:_(<4 x f32>) + %fpext:_(<2 x f64>) = G_FPEXT %unmerge:_(<2 x f32>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -33,40 +33,17 @@ body: | ; CHECK-LABEL: name: v8s16 ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<4 x s16>) = G_EXTRACT_SUBVECTOR %v1(<8 x s16>), 4 - ; CHECK-NEXT: %fpext:_(<4 x s32>) = G_FPEXT %unmerge(<4 x s16>) - ; CHECK-NEXT: $q0 = COPY %fpext(<4 x s32>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %v1(<8 x f16>), 4 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<8 x s16>) = COPY $q0 - %implicit:_(<8 x s16>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<8 x s16>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<4 x s16>), %unused:_(<4 x s16>) = G_UNMERGE_VALUES %ext:_(<8 x s16>) - %fpext:_(<4 x s32>) = G_FPEXT %unmerge:_(<4 x s16>) - $q0 = COPY %fpext - RET_ReallyLR implicit $q0 -... ---- -name: v16s8 -legalized: true -body: | - bb.0.entry: - liveins: $q0 - ; CHECK-LABEL: name: v16s8 - ; CHECK: liveins: $q0 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %v1(<16 x s8>), 8 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) - ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -79,20 +56,20 @@ body: | ; CHECK-LABEL: name: skip_not_const ; CHECK: liveins: $q0, $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = COPY $w0 - ; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = COPY $w0 + ; CHECK-NEXT: %ext:_(<8 x f16>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 0 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = COPY $w0 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = COPY $w0 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... @@ -105,24 +82,24 @@ body: | ; CHECK-LABEL: name: skip_not_unused ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 8 - ; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0 - ; CHECK-NEXT: %unused:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 8 - ; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>) - ; CHECK-NEXT: %fpext2:_(<8 x s16>) = G_FPEXT %unused(<8 x s8>) - ; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>) - ; CHECK-NEXT: $q1 = COPY %fpext2(<8 x s16>) + ; CHECK-NEXT: %v1:_(<8 x f16>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = G_CONSTANT i32 8 + ; CHECK-NEXT: %ext:_(<8 x f16>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 0 + ; CHECK-NEXT: %unused:_(<4 x f16>) = G_EXTRACT_SUBVECTOR %ext(<8 x f16>), 4 + ; CHECK-NEXT: %fpext:_(<4 x f32>) = G_FPEXT %unmerge(<4 x f16>) + ; CHECK-NEXT: %fpext2:_(<4 x f32>) = G_FPEXT %unused(<4 x f16>) + ; CHECK-NEXT: $q0 = COPY %fpext(<4 x f32>) + ; CHECK-NEXT: $q1 = COPY %fpext2(<4 x f32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1 - %v1:_(<16 x s8>) = COPY $q0 - %implicit:_(<16 x s8>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 8 - %ext:_(<16 x s8>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext:_(<16 x s8>) - %fpext:_(<8 x s16>) = G_FPEXT %unmerge:_(<8 x s8>) - %fpext2:_(<8 x s16>) = G_FPEXT %unused:_(<8 x s8>) + %v1:_(<8 x f16>) = COPY $q0 + %implicit:_(<8 x f16>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 8 + %ext:_(<8 x f16>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<4 x f16>), %unused:_(<4 x f16>) = G_UNMERGE_VALUES %ext:_(<8 x f16>) + %fpext:_(<4 x f32>) = G_FPEXT %unmerge:_(<4 x f16>) + %fpext2:_(<4 x f32>) = G_FPEXT %unused:_(<4 x f16>) $q0 = COPY %fpext $q1 = COPY %fpext2 RET_ReallyLR implicit $q0, implicit $q1 @@ -136,20 +113,20 @@ body: | ; CHECK-LABEL: name: skip_borders ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - ; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 9 - ; CHECK-NEXT: %ext:_(<4 x s32>) = G_EXT %v1, %implicit, %C(s32) - ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %ext(<4 x s32>), 0 - ; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>) - ; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>) + ; CHECK-NEXT: %v1:_(<4 x f32>) = COPY $q0 + ; CHECK-NEXT: %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: %C:_(i32) = G_CONSTANT i32 9 + ; CHECK-NEXT: %ext:_(<4 x f32>) = G_EXT %v1, %implicit, %C(i32) + ; CHECK-NEXT: %unmerge:_(<2 x f32>) = G_EXTRACT_SUBVECTOR %ext(<4 x f32>), 0 + ; CHECK-NEXT: %fpext:_(<2 x f64>) = G_FPEXT %unmerge(<2 x f32>) + ; CHECK-NEXT: $q0 = COPY %fpext(<2 x f64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %v1:_(<4 x s32>) = COPY $q0 - %implicit:_(<4 x s32>) = G_IMPLICIT_DEF - %C:_(s32) = G_CONSTANT i32 9 - %ext:_(<4 x s32>) = G_EXT %v1:_, %implicit:_, %C:_(s32) - %unmerge:_(<2 x s32>), %unused:_(<2 x s32>) = G_UNMERGE_VALUES %ext:_(<4 x s32>) - %fpext:_(<2 x s64>) = G_FPEXT %unmerge:_(<2 x s32>) + %v1:_(<4 x f32>) = COPY $q0 + %implicit:_(<4 x f32>) = G_IMPLICIT_DEF + %C:_(i32) = G_CONSTANT i32 9 + %ext:_(<4 x f32>) = G_EXT %v1:_, %implicit:_, %C:_(i32) + %unmerge:_(<2 x f32>), %unused:_(<2 x f32>) = G_UNMERGE_VALUES %ext:_(<4 x f32>) + %fpext:_(<2 x f64>) = G_FPEXT %unmerge:_(<2 x f32>) $q0 = COPY %fpext RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir index 00d5231cd0899..65b51bdab72ba 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-uzp.mir @@ -18,15 +18,15 @@ body: | ; CHECK-LABEL: name: uzp1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x s32>) = G_UZP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x i32>) = G_UZP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 2, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 2, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -41,15 +41,15 @@ body: | ; CHECK-LABEL: name: uzp2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x s32>) = G_UZP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x i32>) = G_UZP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 3, 5, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 3, 5, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -66,15 +66,15 @@ body: | ; CHECK-LABEL: name: no_uzp1 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(0, 1, 4, 6) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(0, 1, 4, 6) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 1, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -91,15 +91,15 @@ body: | ; CHECK-LABEL: name: no_uzp2 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(1, 4, 5, 7) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(1, 4, 5, 7) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 4, 5, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 4, 5, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -116,15 +116,15 @@ body: | ; CHECK-LABEL: name: uzp1_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x s32>) = G_UZP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP1_:%[0-9]+]]:_(<4 x i32>) = G_UZP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, -1, 4, 6) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, -1, 4, 6) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -141,13 +141,13 @@ body: | ; CHECK-LABEL: name: uzp2_undef ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x s32>) = G_UZP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[UZP2_:%[0-9]+]]:_(<4 x i32>) = G_UZP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[UZP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(1, 3, -1, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(1, 3, -1, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir index dfaddba5c7772..f6e2f1d9ea758 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-vashr-vlshr.mir @@ -14,15 +14,15 @@ body: | ; CHECK-LABEL: name: ashr_v4s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[VASHR:%[0-9]+]]:_(<4 x s32>) = G_VASHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VASHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[VASHR:%[0-9]+]]:_(<4 x i32>) = G_VASHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VASHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 5 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_ASHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 5 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_ASHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -37,15 +37,15 @@ body: | ; CHECK-LABEL: name: lshr_v4s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<4 x s32>) = G_VLSHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<4 x i32>) = G_VLSHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 5 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 5 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -60,15 +60,15 @@ body: | ; CHECK-LABEL: name: lshr_v8s16 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0 - ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<8 x s16>) = G_VLSHR [[COPY]], 5 - ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<8 x s16>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x i16>) = COPY $q0 + ; CHECK-NEXT: [[VLSHR:%[0-9]+]]:_(<8 x i16>) = G_VLSHR [[COPY]], 5 + ; CHECK-NEXT: $q0 = COPY [[VLSHR]](<8 x i16>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<8 x s16>) = COPY $q0 - %1:_(s16) = G_CONSTANT i16 5 - %2:_(<8 x s16>) = G_BUILD_VECTOR %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16), %1(s16) - %3:_(<8 x s16>) = G_LSHR %0, %2(<8 x s16>) - $q0 = COPY %3(<8 x s16>) + %0:_(<8 x i16>) = COPY $q0 + %1:_(i16) = G_CONSTANT i16 5 + %2:_(<8 x i16>) = G_BUILD_VECTOR %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16), %1(i16) + %3:_(<8 x i16>) = G_LSHR %0, %2(<8 x i16>) + $q0 = COPY %3(<8 x i16>) RET_ReallyLR implicit $q0 ... --- @@ -83,17 +83,17 @@ body: | ; CHECK-LABEL: name: imm_too_large ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 40 - ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x s32>) = G_DUP [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[DUP]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 40 + ; CHECK-NEXT: [[DUP:%[0-9]+]]:_(<4 x i32>) = G_DUP [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[DUP]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 40 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 40 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -108,17 +108,17 @@ body: | ; CHECK-LABEL: name: imm_zero ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0 - ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32), [[C]](i32), [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 0 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %1(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 0 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %1(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... --- @@ -133,18 +133,18 @@ body: | ; CHECK-LABEL: name: imm_not_splat ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 - ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 6 - ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C1]](s32), [[C]](s32), [[C]](s32) - ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x s32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x s32>) - ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 4 + ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i32) = G_CONSTANT i32 6 + ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C1]](i32), [[C]](i32), [[C]](i32) + ; CHECK-NEXT: [[LSHR:%[0-9]+]]:_(<4 x i32>) = G_LSHR [[COPY]], [[BUILD_VECTOR]](<4 x i32>) + ; CHECK-NEXT: $q0 = COPY [[LSHR]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(s32) = G_CONSTANT i32 4 - %4:_(s32) = G_CONSTANT i32 6 - %2:_(<4 x s32>) = G_BUILD_VECTOR %1(s32), %4(s32), %1(s32), %1(s32) - %3:_(<4 x s32>) = G_LSHR %0, %2(<4 x s32>) - $q0 = COPY %3(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(i32) = G_CONSTANT i32 4 + %4:_(i32) = G_CONSTANT i32 6 + %2:_(<4 x i32>) = G_BUILD_VECTOR %1(i32), %4(i32), %1(i32), %1(i32) + %3:_(<4 x i32>) = G_LSHR %0, %2(<4 x i32>) + $q0 = COPY %3(<4 x i32>) RET_ReallyLR implicit $q0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir index 5c00bfb634ef4..e0f057aa3fd94 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-zip.mir @@ -19,15 +19,15 @@ body: | ; CHECK-LABEL: name: zip1_v2s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP1_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0, 2) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(0, 2) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -43,15 +43,15 @@ body: | ; CHECK-LABEL: name: zip1_v2s64 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x s64>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<2 x i64>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 2) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(0, 2) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -67,15 +67,15 @@ body: | ; CHECK-LABEL: name: zip1_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<4 x s32>) = G_ZIP1 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[ZIP1_:%[0-9]+]]:_(<4 x i32>) = G_ZIP1 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP1_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 4, 1, 5) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(0, 4, 1, 5) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -91,15 +91,15 @@ body: | ; CHECK-LABEL: name: zip2_v2s32 ; CHECK: liveins: $d0, $d1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i32>) = COPY $d0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i32>) = COPY $d1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $d0 = COPY [[ZIP2_]](<2 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s32>) = COPY $d0 - %1:_(<2 x s32>) = COPY $d1 - %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 3) - $d0 = COPY %2(<2 x s32>) + %0:_(<2 x i32>) = COPY $d0 + %1:_(<2 x i32>) = COPY $d1 + %2:_(<2 x i32>) = G_SHUFFLE_VECTOR %0(<2 x i32>), %1, shufflemask(1, 3) + $d0 = COPY %2(<2 x i32>) RET_ReallyLR implicit $d0 ... @@ -115,15 +115,15 @@ body: | ; CHECK-LABEL: name: zip2_v2s64 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x s64>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<2 x i64>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 3) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 3) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -139,15 +139,15 @@ body: | ; CHECK-LABEL: name: zip2_v4s32 ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<4 x s32>) = G_ZIP2 [[COPY]], [[COPY1]] - ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[ZIP2_:%[0-9]+]]:_(<4 x i32>) = G_ZIP2 [[COPY]], [[COPY1]] + ; CHECK-NEXT: $q0 = COPY [[ZIP2_]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(2, 6, 3, 7) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(2, 6, 3, 7) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 ... @@ -165,16 +165,16 @@ body: | ; CHECK-LABEL: name: zip2_no_combine_idx_mismatch ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY $q1 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 8 - ; CHECK-NEXT: [[EXT:%[0-9]+]]:_(<2 x s64>) = G_EXT [[COPY]], [[COPY1]], [[C]](i32) - ; CHECK-NEXT: $q0 = COPY [[EXT]](<2 x s64>) + ; CHECK-NEXT: [[EXT:%[0-9]+]]:_(<2 x i64>) = G_EXT [[COPY]], [[COPY1]], [[C]](i32) + ; CHECK-NEXT: $q0 = COPY [[EXT]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 2) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(1, 2) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -192,14 +192,14 @@ body: | ; CHECK-LABEL: name: zip1_no_combine_idx_mismatch ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY [[COPY]](<2 x s64>) - ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x s64>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x i64>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x i64>) = COPY [[COPY]](<2 x i64>) + ; CHECK-NEXT: $q0 = COPY [[COPY1]](<2 x i64>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<2 x s64>) = COPY $q0 - %1:_(<2 x s64>) = COPY $q1 - %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(0, 1) - $q0 = COPY %2(<2 x s64>) + %0:_(<2 x i64>) = COPY $q0 + %1:_(<2 x i64>) = COPY $q1 + %2:_(<2 x i64>) = G_SHUFFLE_VECTOR %0(<2 x i64>), %1, shufflemask(0, 1) + $q0 = COPY %2(<2 x i64>) RET_ReallyLR implicit $q0 ... @@ -216,13 +216,13 @@ body: | ; CHECK-LABEL: name: no_combine_first_elt_of_mask_must_be_zero_or_one ; CHECK: liveins: $q0, $q1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x s32>), [[COPY1]], shufflemask(3, 4, 1, 5) - ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x s32>) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x i32>) = COPY $q0 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x i32>) = COPY $q1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<4 x i32>) = G_SHUFFLE_VECTOR [[COPY]](<4 x i32>), [[COPY1]], shufflemask(3, 4, 1, 5) + ; CHECK-NEXT: $q0 = COPY [[SHUF]](<4 x i32>) ; CHECK-NEXT: RET_ReallyLR implicit $q0 - %0:_(<4 x s32>) = COPY $q0 - %1:_(<4 x s32>) = COPY $q1 - %2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(3, 4, 1, 5) - $q0 = COPY %2(<4 x s32>) + %0:_(<4 x i32>) = COPY $q0 + %1:_(<4 x i32>) = COPY $q1 + %2:_(<4 x i32>) = G_SHUFFLE_VECTOR %0(<4 x i32>), %1, shufflemask(3, 4, 1, 5) + $q0 = COPY %2(<4 x i32>) RET_ReallyLR implicit $q0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir index f4dc5ecd4e03f..565bdde81fe0d 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extending-loads.mir @@ -24,11 +24,11 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(s32) = G_ZEXTLOAD [[COPY]](p0) :: (load (s8) from %ir.addr) - ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](s32) + ; CHECK-NEXT: [[ZEXTLOAD:%[0-9]+]]:_(i32) = G_ZEXTLOAD [[COPY]](p0) :: (load (i8) from %ir.addr) + ; CHECK-NEXT: $w0 = COPY [[ZEXTLOAD]](i32) %0:_(p0) = COPY $x0 - %1:_(s8) = G_LOAD %0 :: (load (s8) from %ir.addr) - %2:_(s32) = G_ZEXT %1 + %1:_(i8) = G_LOAD %0 :: (load (i8) from %ir.addr) + %2:_(i32) = G_ZEXT %1 $w0 = COPY %2 ... @@ -42,10 +42,10 @@ body: | ; CHECK: liveins: $x0 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s64) = G_LOAD [[COPY]](p0) :: (load (s32) from %ir.addr) - ; CHECK-NEXT: $x0 = COPY [[LOAD]](s64) + ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(i64) = G_LOAD [[COPY]](p0) :: (load (i32) from %ir.addr) + ; CHECK-NEXT: $x0 = COPY [[LOAD]](i64) %0:_(p0) = COPY $x0 - %1:_(s32) = G_LOAD %0 :: (load (s32) from %ir.addr) - %2:_(s64) = G_ANYEXT %1 + %1:_(i32) = G_LOAD %0 :: (load (i32) from %ir.addr) + %2:_(i64) = G_ANYEXT %1 $x0 = COPY %2 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir index 819a81a472788..8d659c00ce8dc 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-extractvec-faddp.mir @@ -14,21 +14,21 @@ body: | ; CHECK-LABEL: name: f64_faddp ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $d0 = COPY [[FADD]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f64) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $d0 = COPY [[FADD]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -46,21 +46,21 @@ body: | ; CHECK-LABEL: name: f64_faddp_commuted ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s64>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s64) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $d0 = COPY [[FADD]](s64) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f64>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f64) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $d0 = COPY [[FADD]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %0, %1 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %0, %1 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -78,21 +78,21 @@ body: | ; CHECK-LABEL: name: f32_faddp ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $s0 = COPY [[FADD]](s32) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $s0 = COPY [[FADD]](f32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:_(<2 x s32>) = COPY $d0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - %3:_(<2 x s32>) = G_FADD %1, %0 - %4:_(s32) = G_EXTRACT_VECTOR_ELT %3(<2 x s32>), %5(s64) - $s0 = COPY %4(s32) + %0:_(<2 x f32>) = COPY $d0 + %2:_(<2 x f32>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f32>) = G_SHUFFLE_VECTOR %0(<2 x f32>), %2, shufflemask(1, undef) + %3:_(<2 x f32>) = G_FADD %1, %0 + %4:_(f32) = G_EXTRACT_VECTOR_ELT %3(<2 x f32>), %5(i64) + $s0 = COPY %4(f32) RET_ReallyLR implicit $s0 ... @@ -110,21 +110,21 @@ body: | ; CHECK-LABEL: name: f32_faddp_commuted ; CHECK: liveins: $d0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f32>) = COPY $d0 ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](i64) + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C]](i64) ; CHECK-NEXT: [[C1:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C1]](i64) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[EVEC]], [[EVEC1]] - ; CHECK-NEXT: $s0 = COPY [[FADD]](s32) + ; CHECK-NEXT: [[EVEC1:%[0-9]+]]:_(f32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x f32>), [[C1]](i64) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(f32) = G_FADD [[EVEC]], [[EVEC1]] + ; CHECK-NEXT: $s0 = COPY [[FADD]](f32) ; CHECK-NEXT: RET_ReallyLR implicit $s0 - %0:_(<2 x s32>) = COPY $d0 - %2:_(<2 x s32>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1, undef) - %3:_(<2 x s32>) = G_FADD %0, %1 - %4:_(s32) = G_EXTRACT_VECTOR_ELT %3(<2 x s32>), %5(s64) - $s0 = COPY %4(s32) + %0:_(<2 x f32>) = COPY $d0 + %2:_(<2 x f32>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f32>) = G_SHUFFLE_VECTOR %0(<2 x f32>), %2, shufflemask(1, undef) + %3:_(<2 x f32>) = G_FADD %0, %1 + %4:_(f32) = G_EXTRACT_VECTOR_ELT %3(<2 x f32>), %5(i64) + $s0 = COPY %4(f32) RET_ReallyLR implicit $s0 ... @@ -142,21 +142,21 @@ body: | ; CHECK-LABEL: name: wrong_extract_idx ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[DEF]], shufflemask(1, undef) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x s64>) = G_FADD [[SHUF]], [[COPY]] - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x s64>), [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x f64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 1 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x f64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x f64>), [[DEF]], shufflemask(1, undef) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x f64>) = G_FADD [[SHUF]], [[COPY]] + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x f64>), [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 1 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(1, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 1 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(1, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... @@ -174,21 +174,21 @@ body: | ; CHECK-LABEL: name: wrong_shuffle_mask ; CHECK: liveins: $q0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0 - ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x s64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x s64>), [[DEF]], shufflemask(0, undef) - ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x s64>) = G_FADD [[SHUF]], [[COPY]] - ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x s64>), [[C]](s64) - ; CHECK-NEXT: $d0 = COPY [[EVEC]](s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x f64>) = COPY $q0 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<2 x f64>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[SHUF:%[0-9]+]]:_(<2 x f64>) = G_SHUFFLE_VECTOR [[COPY]](<2 x f64>), [[DEF]], shufflemask(0, undef) + ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(<2 x f64>) = G_FADD [[SHUF]], [[COPY]] + ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(f64) = G_EXTRACT_VECTOR_ELT [[FADD]](<2 x f64>), [[C]](i64) + ; CHECK-NEXT: $d0 = COPY [[EVEC]](f64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - %0:_(<2 x s64>) = COPY $q0 - %2:_(<2 x s64>) = G_IMPLICIT_DEF - %5:_(s64) = G_CONSTANT i64 0 - %1:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %2, shufflemask(0, undef) - %3:_(<2 x s64>) = G_FADD %1, %0 - %4:_(s64) = G_EXTRACT_VECTOR_ELT %3(<2 x s64>), %5(s64) - $d0 = COPY %4(s64) + %0:_(<2 x f64>) = COPY $q0 + %2:_(<2 x f64>) = G_IMPLICIT_DEF + %5:_(i64) = G_CONSTANT i64 0 + %1:_(<2 x f64>) = G_SHUFFLE_VECTOR %0(<2 x f64>), %2, shufflemask(0, undef) + %3:_(<2 x f64>) = G_FADD %1, %0 + %4:_(f64) = G_EXTRACT_VECTOR_ELT %3(<2 x f64>), %5(i64) + $d0 = COPY %4(f64) RET_ReallyLR implicit $d0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir index 8e0121f922849..4ab3721440934 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-hoist-same-hands.mir @@ -13,18 +13,18 @@ body: | ; CHECK-LABEL: name: or_combine_sext ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: [[OR:%[0-9]+]]:_(s32) = G_OR %x, %y - ; CHECK-NEXT: %logic_op:_(s64) = G_SEXT [[OR]](s32) - ; CHECK-NEXT: $x0 = COPY %logic_op(s64) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: [[OR:%[0-9]+]]:_(i32) = G_OR %x, %y + ; CHECK-NEXT: %logic_op:_(i64) = G_SEXT [[OR]](i32) + ; CHECK-NEXT: $x0 = COPY %logic_op(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %hand1:_(s64) = G_SEXT %x(s32) - %hand2:_(s64) = G_SEXT %y(s32) - %logic_op:_(s64) = G_OR %hand1, %hand2 - $x0 = COPY %logic_op(s64) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %hand1:_(i64) = G_SEXT %x(i32) + %hand2:_(i64) = G_SEXT %y(i32) + %logic_op:_(i64) = G_OR %hand1, %hand2 + $x0 = COPY %logic_op(i64) RET_ReallyLR implicit $x0 ... @@ -40,23 +40,23 @@ body: | ; CHECK-LABEL: name: illegal_ty ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x_wide:_(s32) = COPY $w0 - ; CHECK-NEXT: %y_wide:_(s32) = COPY $w1 - ; CHECK-NEXT: %x:_(s1) = G_TRUNC %x_wide(s32) - ; CHECK-NEXT: %y:_(s1) = G_TRUNC %y_wide(s32) - ; CHECK-NEXT: %hand1:_(s64) = G_SEXT %x(s1) - ; CHECK-NEXT: %hand2:_(s64) = G_SEXT %y(s1) - ; CHECK-NEXT: %logic_op:_(s64) = G_OR %hand1, %hand2 - ; CHECK-NEXT: $x0 = COPY %logic_op(s64) + ; CHECK-NEXT: %x_wide:_(i32) = COPY $w0 + ; CHECK-NEXT: %y_wide:_(i32) = COPY $w1 + ; CHECK-NEXT: %x:_(i1) = G_TRUNC %x_wide(i32) + ; CHECK-NEXT: %y:_(i1) = G_TRUNC %y_wide(i32) + ; CHECK-NEXT: %hand1:_(i64) = G_SEXT %x(i1) + ; CHECK-NEXT: %hand2:_(i64) = G_SEXT %y(i1) + ; CHECK-NEXT: %logic_op:_(i64) = G_OR %hand1, %hand2 + ; CHECK-NEXT: $x0 = COPY %logic_op(i64) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %x_wide:_(s32) = COPY $w0 - %y_wide:_(s32) = COPY $w1 - %x:_(s1) = G_TRUNC %x_wide - %y:_(s1) = G_TRUNC %y_wide - %hand1:_(s64) = G_SEXT %x(s1) - %hand2:_(s64) = G_SEXT %y(s1) - %logic_op:_(s64) = G_OR %hand1, %hand2 - $x0 = COPY %logic_op(s64) + %x_wide:_(i32) = COPY $w0 + %y_wide:_(i32) = COPY $w1 + %x:_(i1) = G_TRUNC %x_wide + %y:_(i1) = G_TRUNC %y_wide + %hand1:_(i64) = G_SEXT %x(i1) + %hand2:_(i64) = G_SEXT %y(i1) + %logic_op:_(i64) = G_OR %hand1, %hand2 + $x0 = COPY %logic_op(i64) RET_ReallyLR implicit $x0 ... @@ -71,13 +71,13 @@ body: | ; CHECK-LABEL: name: dont_combine_physreg ; CHECK: liveins: $w0, $w1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %x:_(s32) = COPY $w0 - ; CHECK-NEXT: %y:_(s32) = COPY $w1 - ; CHECK-NEXT: %logic_op:_(s32) = G_OR %x, %y - ; CHECK-NEXT: $w0 = COPY %logic_op(s32) + ; CHECK-NEXT: %x:_(i32) = COPY $w0 + ; CHECK-NEXT: %y:_(i32) = COPY $w1 + ; CHECK-NEXT: %logic_op:_(i32) = G_OR %x, %y + ; CHECK-NEXT: $w0 = COPY %logic_op(i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %x:_(s32) = COPY $w0 - %y:_(s32) = COPY $w1 - %logic_op:_(s32) = G_OR %x, %y - $w0 = COPY %logic_op(s32) + %x:_(i32) = COPY $w0 + %y:_(i32) = COPY $w1 + %logic_op:_(i32) = G_OR %x, %y + $w0 = COPY %logic_op(i32) RET_ReallyLR implicit $w0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir index 7cba6b78c5b4e..f9bc49db4a1f5 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-mulpow2.mir @@ -15,19 +15,19 @@ body: | ; CHECK-LABEL: name: dont_combine_ptr_add ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: %reg0:_(s64) = COPY $x0 - ; CHECK-NEXT: %reg1:_(s64) = COPY $x1 + ; CHECK-NEXT: %reg0:_(i64) = COPY $x0 + ; CHECK-NEXT: %reg1:_(i64) = COPY $x1 ; CHECK-NEXT: %ptr:_(p0) = COPY $x2 - ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 6 - ; CHECK-NEXT: %mul:_(s64) = nsw G_MUL %reg0, %cst - ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul(s64) + ; CHECK-NEXT: %cst:_(i64) = G_CONSTANT i64 6 + ; CHECK-NEXT: %mul:_(i64) = nsw G_MUL %reg0, %cst + ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul(i64) ; CHECK-NEXT: $x0 = COPY %ptr_add(p0) ; CHECK-NEXT: RET_ReallyLR implicit $x0 - %reg0:_(s64) = COPY $x0 - %reg1:_(s64) = COPY $x1 + %reg0:_(i64) = COPY $x0 + %reg1:_(i64) = COPY $x1 %ptr:_(p0) = COPY $x2 - %cst:_(s64) = G_CONSTANT i64 6 - %mul:_(s64) = nsw G_MUL %reg0, %cst + %cst:_(i64) = G_CONSTANT i64 6 + %mul:_(i64) = nsw G_MUL %reg0, %cst %ptr_add:_(p0) = G_PTR_ADD %ptr, %mul $x0 = COPY %ptr_add(p0) RET_ReallyLR implicit $x0 diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir index 2bb4f00bcde72..4229c53649322 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-rotate.mir @@ -17,15 +17,15 @@ body: | ; CHECK-LABEL: name: rotl ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 -16 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 -16 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -43,15 +43,15 @@ body: | ; CHECK-LABEL: name: rotr ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16 - ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTR]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 16 + ; CHECK-NEXT: [[ROTR:%[0-9]+]]:_(i32) = G_ROTR [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTR]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 -16 - %2:_(s32) = G_ROTR %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 -16 + %2:_(i32) = G_ROTR %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -69,15 +69,15 @@ body: | ; CHECK-LABEL: name: rotl_bitwidth_cst ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 32 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 32 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... @@ -95,15 +95,15 @@ body: | ; CHECK-LABEL: name: rotl_bitwidth_minus_one_cst ; CHECK: liveins: $w0 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 - ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 31 - ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[COPY]], [[C]](s64) - ; CHECK-NEXT: $w0 = COPY [[ROTL]](s32) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0 + ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 31 + ; CHECK-NEXT: [[ROTL:%[0-9]+]]:_(i32) = G_ROTL [[COPY]], [[C]](i64) + ; CHECK-NEXT: $w0 = COPY [[ROTL]](i32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - %0:_(s32) = COPY $w0 - %5:_(s64) = G_CONSTANT i64 31 - %2:_(s32) = G_ROTL %0, %5(s64) - $w0 = COPY %2(s32) + %0:_(i32) = COPY $w0 + %5:_(i64) = G_CONSTANT i64 31 + %2:_(i32) = G_ROTL %0, %5(i64) + $w0 = COPY %2(i32) RET_ReallyLR implicit $w0 ... diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir index ac0d561c99a1b..c2c457884c786 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizercombiner-select.mir @@ -10,12 +10,12 @@ body: | ; CHECK-LABEL: name: test_combine_select_same_res ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s1) = G_TRUNC %0 - %2:_(s64) = G_SELECT %1, %0, %0 - $x0 = COPY %2(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i1) = G_TRUNC %0 + %2:_(i64) = G_SELECT %1, %0, %0 + $x0 = COPY %2(i64) ... --- # select (undef, x, y) -> y @@ -27,13 +27,13 @@ body: | ; CHECK-LABEL: name: test_combine_select_undef_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_IMPLICIT_DEF - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_IMPLICIT_DEF + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... --- # select (false, x, y) -> y @@ -45,13 +45,13 @@ body: | ; CHECK-LABEL: name: test_combine_select_false_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_CONSTANT i1 false - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x1 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_CONSTANT i1 false + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... --- # select (true, x, y) -> x @@ -63,11 +63,11 @@ body: | ; CHECK-LABEL: name: test_combine_select_true_res0_res1 ; CHECK: liveins: $x0, $x1 ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: $x0 = COPY [[COPY]](s64) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s1) = G_CONSTANT i1 true - %3:_(s64) = G_SELECT %2, %0, %1 - $x0 = COPY %3(s64) + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i64) = COPY $x0 + ; CHECK-NEXT: $x0 = COPY [[COPY]](i64) + %0:_(i64) = COPY $x0 + %1:_(i64) = COPY $x1 + %2:_(i1) = G_CONSTANT i1 true + %3:_(i64) = G_SELECT %2, %0, %1 + $x0 = COPY %3(i64) ... From 3c138b5c5958dce2daefa923a1cae612e47a4273 Mon Sep 17 00:00:00 2001 From: Emery Conrad Date: Fri, 10 Jul 2026 07:28:32 +0200 Subject: [PATCH 070/125] Reland "[ORC] Track __emutls_t definitions in IRMaterializationUnit" (#207161) (#208413) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relands #207161, which was reverted in #207775 after the new `clang/test/Interpreter/emulated-tls.cpp` failed on Darwin with `Symbols not found: [ ___emutls_get_address ]`. The `IRMaterializationUnit` fix and the test are unchanged from #207161. What the failure exposed is that thread_locals never worked in clang-repl on Darwin: `__emutls_get_address` is implemented in the compiler-rt builtins static archive, and nothing links it into the process, so process-symbol lookup cannot resolve it (on Linux it resolves from `libgcc_s.so`). New in this reland, per @lhames's suggestion (option 2) on the original PR: - `clang/lib/Interpreter/IncrementalExecutor.cpp`: on `__APPLE__`, reference `__emutls_get_address` (forcing the builtins archive member to be linked in) and define it as an absolute symbol in the process-symbols JITDylib, following the precedent of the MinGW `__main` workaround in `lli.cpp`. Scoped to the default in-process JITBuilder path only — the host address would be meaningless for an out-of-process executor, and custom-builder clients do their own setup. Verified on an aarch64-darwin machine: the previously failing test now passes, along with the rest of `clang/test/Interpreter`. @vgvassilev @lhames — could you take a look? 🤖 Done with the help of [Claude Code](https://claude.com/claude-code) (Claude Opus 4.8, human in the loop) Co-authored-by: Emery Conrad --- clang/lib/Interpreter/IncrementalExecutor.cpp | 39 +++++++++++++++++++ clang/test/Interpreter/emulated-tls.cpp | 25 ++++++++++++ llvm/lib/ExecutionEngine/Orc/Layer.cpp | 1 + 3 files changed, 65 insertions(+) create mode 100644 clang/test/Interpreter/emulated-tls.cpp diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp index 65cb29a2f441a..8e64a3d73305e 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/IncrementalExecutor.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" @@ -60,6 +61,21 @@ #include #endif +// Address of the host's emulated-TLS runtime entry point, or null if the host +// cannot provide one. On Darwin, __emutls_get_address lives in the compiler-rt +// builtins archive; referencing it here force-links the archive member into +// the binary. The reference must not exist elsewhere: MSVC has no emulated-TLS +// runtime (the link would fail), and ELF hosts resolve it from libgcc_s / +// compiler-rt through regular process-symbol lookup. +#ifdef __APPLE__ +extern "C" void *__emutls_get_address(void *); +static void *getEmuTLSGetAddressPtr() { + return reinterpret_cast(&__emutls_get_address); +} +#else +static void *getEmuTLSGetAddressPtr() { return nullptr; } +#endif + namespace clang { IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default; @@ -388,6 +404,29 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, if (!JB) return JB.takeError(); JITBuilder = std::move(*JB); + // TODO: Switch to native TLS on Darwin once clang-repl can adopt the ORC + // runtime (which provides __emutls_get_address and supports the full TLS + // lifecycle). That will also remove the in-process-only constraint below. + // + // For MachO targets, thread_locals are lowered to emulated TLS, but the + // runtime (__emutls_get_address) lives in the compiler-rt builtins archive + // and nothing else in this process references it, so it isn't linked in + // and process-symbol lookup cannot find it. Define the force-linked host + // symbol (see getEmuTLSGetAddressPtr) as an absolute symbol so it is + // visible to JIT'd code. In-process execution only: the address is + // meaningless in an out-of-process executor. + if (void *EmuTLSGetAddress = getEmuTLSGetAddressPtr(); + EmuTLSGetAddress && TT.isOSBinFormatMachO()) + JITBuilder->setNotifyCreatedCallback( + [EmuTLSGetAddress](llvm::orc::LLJIT &J) { + auto &JD = J.getProcessSymbolsJITDylib() + ? *J.getProcessSymbolsJITDylib() + : J.getMainJITDylib(); + return JD.define(llvm::orc::absoluteSymbols( + {{J.mangleAndIntern("__emutls_get_address"), + {llvm::orc::ExecutorAddr::fromPtr(EmuTLSGetAddress), + llvm::JITSymbolFlags::Exported}}})); + }); } llvm::Error Err = llvm::Error::success(); diff --git a/clang/test/Interpreter/emulated-tls.cpp b/clang/test/Interpreter/emulated-tls.cpp new file mode 100644 index 0000000000000..73afe172ef6d9 --- /dev/null +++ b/clang/test/Interpreter/emulated-tls.cpp @@ -0,0 +1,25 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-windows +// +// An inline function that odr-uses a non-zero-initialized thread_local is +// emitted as a weak (linkonce_odr) definition into every PartialTranslationUnit +// that references it. With emulated TLS that set includes an __emutls_t. +// symbol. When a later PTU re-defines the same weak set, ORC's +// IRMaterializationUnit::discard() must find each duplicated symbol in its +// SymbolToDefinition map. The emulated-TLS path used to register __emutls_t. +// in SymbolFlags but not SymbolToDefinition, so discarding it dereferenced +// end() -- an assertion failure in +Asserts builds and heap corruption +// otherwise. Two PTUs each pulling in the same inline worker reproduces it. +// +// RUN: cat %s | clang-repl | FileCheck %s + +extern "C" int printf(const char *, ...); +template struct HeavyThing { static thread_local int tls; }; +template thread_local int HeavyThing::tls = Tag + 1; +inline int worker() { return HeavyThing<1>::tls; } +int callA() { return worker(); } +int callB() { return worker(); } +auto r = printf("tls = %d, %d\n", callA(), callB()); +// CHECK: tls = 2, 2 + +%quit diff --git a/llvm/lib/ExecutionEngine/Orc/Layer.cpp b/llvm/lib/ExecutionEngine/Orc/Layer.cpp index eb144275da589..5e95b8c73b482 100644 --- a/llvm/lib/ExecutionEngine/Orc/Layer.cpp +++ b/llvm/lib/ExecutionEngine/Orc/Layer.cpp @@ -70,6 +70,7 @@ IRMaterializationUnit::IRMaterializationUnit( auto EmuTLST = Mangle(("__emutls_t." + GV.getName()).str()); SymbolFlags[EmuTLST] = Flags; + SymbolToDefinition[EmuTLST] = &GV; } continue; } From 3ce1af9f73de5577ed611d93440a751e68d467cb Mon Sep 17 00:00:00 2001 From: David Green Date: Fri, 10 Jul 2026 07:20:16 +0100 Subject: [PATCH 071/125] [AArch64][GlobalISel] Add bf16 vecreduce test coverage. NFC (#208628) --- .../CodeGen/AArch64/bf16-v4-instructions.ll | 593 ++++++++++ .../CodeGen/AArch64/bf16-v8-instructions.ll | 1017 +++++++++++++++++ 2 files changed, 1610 insertions(+) diff --git a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll index 6c6a9714f7deb..f1808fb4e87c0 100644 --- a/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll +++ b/llvm/test/CodeGen/AArch64/bf16-v4-instructions.ll @@ -20,6 +20,12 @@ ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum ; ; CHECK-BF16-GI: warning: Instruction selection used fallback path for test_fptosi_i8 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_fptosi_i16 @@ -37,6 +43,13 @@ ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum +; ; define <4 x bfloat> @test_build(<4 x bfloat> %a) { @@ -6504,4 +6517,584 @@ define <4 x bfloat> @test_fmuladd(<4 x bfloat> %a, <4 x bfloat> %b, <4 x bfloat> ret <4 x bfloat> %r } +define bfloat @test_reduce_fadd(bfloat %a, <4 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fadd: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: mov h1, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fadd: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fadd(bfloat %a, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fadd_fast(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fadd_fast: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fadd s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fadd s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fadd s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd_fast: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: mov h3, v0.h[2] +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v3.4s, v3.4h, #16 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: fadd s1, s3, s2 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fadd(bfloat -0.0, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul(bfloat %a, <4 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fmul: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmul: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: mov h1, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fmul: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: // kill: def $d1 killed $d1 def $q1 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmul(bfloat %a, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul_fast(<4 x bfloat> %b) #0 { +; CHECK-LABEL: test_reduce_fmul_fast: +; CHECK: // %bb.0: +; CHECK-NEXT: movi d0, #0000000000000000 +; CHECK-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fmul(bfloat -0.0, <4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmin(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmin: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmin: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmin(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmax(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmax: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmax: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmax(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fminimum(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fminimum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fminimum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fminimum(<4 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmaximum(<4 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmaximum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: mov h0, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmaximum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: mov h0, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmaximum(<4 x bfloat> %b) + ret bfloat %r +} + attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll index 971d9e2a6e2b5..2453b36f0873d 100644 --- a/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll +++ b/llvm/test/CodeGen/AArch64/bf16-v8-instructions.ll @@ -25,6 +25,12 @@ ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-CVT-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum ; ; CHECK-BF16-GI: warning: Instruction selection used fallback path for test_fptosi_i8 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_fptosi_v16i8 @@ -46,6 +52,13 @@ ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i16 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i32 ; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_uitofp_i64 +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fadd_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmul_fast +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmin +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmax +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fminimum +; CHECK-BF16-GI-NEXT: warning: Instruction selection used fallback path for test_reduce_fmaximum +; ; define <8 x bfloat> @test_build(<8 x bfloat> %a) { @@ -13769,4 +13782,1008 @@ define <8 x bfloat> @test_fmuladd(<8 x bfloat> %a, <8 x bfloat> %b, <8 x bfloat> ret <8 x bfloat> %r } +define bfloat @test_reduce_fadd(bfloat %a, <8 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fadd: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[4] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[5] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[6] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[7] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fadd s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[4] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[5] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[6] +; CHECK-BF16-NEXT: mov h1, v1.h[7] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fadd: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[4] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[5] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[6] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[7] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fadd s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fadd(bfloat %a, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fadd_fast(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fadd_fast: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: shll2 v1.4s, v0.8h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: fadd v0.4s, v0.4s, v1.4s +; CHECK-CVT-NEXT: faddp v0.4s, v0.4s, v0.4s +; CHECK-CVT-NEXT: faddp s0, v0.2s +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fadd_fast: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: shll2 v1.4s, v0.8h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fadd v0.4s, v0.4s, v1.4s +; CHECK-BF16-NEXT: faddp v0.4s, v0.4s, v0.4s +; CHECK-BF16-NEXT: faddp s0, v0.2s +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fadd(bfloat -0.0, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul(bfloat %a, <8 x bfloat> %b) #0 { +; CHECK-CVT-SD-LABEL: test_reduce_fmul: +; CHECK-CVT-SD: // %bb.0: +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-SD-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s0, s2 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[1] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[2] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[3] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[4] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[5] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[6] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s2, w9 +; CHECK-CVT-SD-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s2, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: mov h0, v1.h[7] +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w9, w9, w8 +; CHECK-CVT-SD-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-SD-NEXT: add w9, w10, w9 +; CHECK-CVT-SD-NEXT: lsr w9, w9, #16 +; CHECK-CVT-SD-NEXT: fmov s1, w9 +; CHECK-CVT-SD-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-SD-NEXT: fmul s0, s1, s0 +; CHECK-CVT-SD-NEXT: fmov w9, s0 +; CHECK-CVT-SD-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-SD-NEXT: add w8, w9, w8 +; CHECK-CVT-SD-NEXT: add w8, w10, w8 +; CHECK-CVT-SD-NEXT: lsr w8, w8, #16 +; CHECK-CVT-SD-NEXT: fmov s0, w8 +; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-SD-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmul: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-BF16-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[1] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[2] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[3] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[4] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[5] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: mov h2, v1.h[6] +; CHECK-BF16-NEXT: mov h1, v1.h[7] +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s2 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: fmul s0, s0, s1 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret +; +; CHECK-CVT-GI-LABEL: test_reduce_fmul: +; CHECK-CVT-GI: // %bb.0: +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0 +; CHECK-CVT-GI-NEXT: shll v2.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s0, s2 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[1] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[2] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[3] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[4] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[5] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[6] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s2, w9 +; CHECK-CVT-GI-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s2, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: mov h0, v1.h[7] +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w11, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-GI-NEXT: add w10, w11, w10 +; CHECK-CVT-GI-NEXT: csel w9, w9, w10, vs +; CHECK-CVT-GI-NEXT: lsr w9, w9, #16 +; CHECK-CVT-GI-NEXT: fmov s1, w9 +; CHECK-CVT-GI-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-GI-NEXT: fmul s0, s1, s0 +; CHECK-CVT-GI-NEXT: fmov w9, s0 +; CHECK-CVT-GI-NEXT: fcmp s0, #0.0 +; CHECK-CVT-GI-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-GI-NEXT: add w8, w9, w8 +; CHECK-CVT-GI-NEXT: orr w9, w9, #0x400000 +; CHECK-CVT-GI-NEXT: add w8, w8, w10 +; CHECK-CVT-GI-NEXT: csel w8, w9, w8, vs +; CHECK-CVT-GI-NEXT: lsr w8, w8, #16 +; CHECK-CVT-GI-NEXT: fmov s0, w8 +; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-GI-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmul(bfloat %a, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmul_fast(<8 x bfloat> %b) #0 { +; CHECK-LABEL: test_reduce_fmul_fast: +; CHECK: // %bb.0: +; CHECK-NEXT: movi d0, #0000000000000000 +; CHECK-NEXT: ret + %r = call fast bfloat @llvm.vector.reduce.fmul(bfloat -0.0, <8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmin(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmin: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fminnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fminnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmin: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fminnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmin(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmax(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmax: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmaxnm s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmax: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmaxnm s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmax(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fminimum(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fminimum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmin s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmin s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fminimum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmin s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fminimum(<8 x bfloat> %b) + ret bfloat %r +} + +define bfloat @test_reduce_fmaximum(<8 x bfloat> %b) #0 { +; CHECK-CVT-LABEL: test_reduce_fmaximum: +; CHECK-CVT: // %bb.0: +; CHECK-CVT-NEXT: mov h1, v0.h[1] +; CHECK-CVT-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-CVT-NEXT: mov w8, #32767 // =0x7fff +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[2] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[3] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[4] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[5] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: mov h1, v0.h[6] +; CHECK-CVT-NEXT: mov h0, v0.h[7] +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s2, w9 +; CHECK-CVT-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-CVT-NEXT: fmax s1, s2, s1 +; CHECK-CVT-NEXT: fmov w9, s1 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w9, w9, w8 +; CHECK-CVT-NEXT: add w9, w10, w9 +; CHECK-CVT-NEXT: lsr w9, w9, #16 +; CHECK-CVT-NEXT: fmov s1, w9 +; CHECK-CVT-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-CVT-NEXT: fmax s0, s1, s0 +; CHECK-CVT-NEXT: fmov w9, s0 +; CHECK-CVT-NEXT: ubfx w10, w9, #16, #1 +; CHECK-CVT-NEXT: add w8, w9, w8 +; CHECK-CVT-NEXT: add w8, w10, w8 +; CHECK-CVT-NEXT: lsr w8, w8, #16 +; CHECK-CVT-NEXT: fmov s0, w8 +; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0 +; CHECK-CVT-NEXT: ret +; +; CHECK-BF16-LABEL: test_reduce_fmaximum: +; CHECK-BF16: // %bb.0: +; CHECK-BF16-NEXT: mov h1, v0.h[1] +; CHECK-BF16-NEXT: shll v2.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s2, s1 +; CHECK-BF16-NEXT: mov h2, v0.h[2] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[3] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[4] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[5] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: mov h2, v0.h[6] +; CHECK-BF16-NEXT: mov h0, v0.h[7] +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v2.4s, v2.4h, #16 +; CHECK-BF16-NEXT: shll v0.4s, v0.4h, #16 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s1, s1, s2 +; CHECK-BF16-NEXT: bfcvt h1, s1 +; CHECK-BF16-NEXT: shll v1.4s, v1.4h, #16 +; CHECK-BF16-NEXT: fmax s0, s1, s0 +; CHECK-BF16-NEXT: bfcvt h0, s0 +; CHECK-BF16-NEXT: ret + %r = call bfloat @llvm.vector.reduce.fmaximum(<8 x bfloat> %b) + ret bfloat %r +} + attributes #0 = { nounwind } From 9bfd0ff9143d96c249e55180b0bfe0e39516cc81 Mon Sep 17 00:00:00 2001 From: Longsheng Mou Date: Fri, 10 Jul 2026 14:28:40 +0800 Subject: [PATCH 072/125] [mlir][emitc] Fix hasSideEffects of emitc.cast (#208607) When `pure` attribute is set, the cast op is side-effect-free, so we should return false in `hasSideEffects` method. --- mlir/include/mlir/Dialect/EmitC/IR/EmitC.td | 2 +- mlir/test/Target/Cpp/expressions.mlir | 42 ++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td index 1b776519b1428..d42c74e963769 100644 --- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td +++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td @@ -404,7 +404,7 @@ def EmitC_CastOp : EmitC_Op<"cast", bool hasSideEffects() { // Use the "pure" attribute to see whether this CastOp has side effects. // Note that by default, `pure` is not set. - return getPure(); + return !getPure(); } }]; } diff --git a/mlir/test/Target/Cpp/expressions.mlir b/mlir/test/Target/Cpp/expressions.mlir index d447f9a38f3d3..43e43cda49477 100644 --- a/mlir/test/Target/Cpp/expressions.mlir +++ b/mlir/test/Target/Cpp/expressions.mlir @@ -89,11 +89,14 @@ func.func @do_not_inline(%arg0: i32, %arg1: i32, %arg2 : i32) -> i32 { } // CPP-DEFAULT: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { -// CPP-DEFAULT-NEXT: return (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DEFAULT-NEXT: float [[VAL_4:v[0-9]+]] = (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DEFAULT-NEXT: return [[VAL_4]]; // CPP-DEFAULT-NEXT: } // CPP-DECLTOP: float parentheses_for_low_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { -// CPP-DECLTOP-NEXT: return (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DECLTOP-NEXT: float [[VAL_4:v[0-9]+]]; +// CPP-DECLTOP-NEXT: [[VAL_4]] = (float) (([[VAL_1]] + [[VAL_2]]) * [[VAL_3]]); +// CPP-DECLTOP-NEXT: return [[VAL_4]]; // CPP-DECLTOP-NEXT: } func.func @parentheses_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> f32 { @@ -106,6 +109,41 @@ func.func @parentheses_for_low_precedence(%arg0: i32, %arg1: i32, %arg2: i32) -> return %e : f32 } +// CPP-DEFAULT: float inline_cast_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DEFAULT-NEXT: return (float) [[VAL_1]]; +// CPP-DEFAULT-NEXT: } + +// CPP-DECLTOP: float inline_cast_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DECLTOP-NEXT: return (float) [[VAL_1]]; +// CPP-DECLTOP-NEXT: } + +func.func @inline_cast_pure(%arg0: i32) -> f32 { + %0 = emitc.expression %arg0 : (i32) -> f32 { + %1 = cast %arg0 {pure} : i32 to f32 + yield %1 : f32 + } + return %0 : f32 +} + +// CPP-DEFAULT: float do_not_inline_cast_without_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DEFAULT-NEXT: float [[VAL_2:v[0-9]+]] = (float) [[VAL_1]]; +// CPP-DEFAULT-NEXT: return [[VAL_2]]; +// CPP-DEFAULT-NEXT: } + +// CPP-DECLTOP: float do_not_inline_cast_without_pure(int32_t [[VAL_1:v[0-9]+]]) { +// CPP-DECLTOP-NEXT: float [[VAL_2:v[0-9]+]]; +// CPP-DECLTOP-NEXT: [[VAL_2]] = (float) [[VAL_1]]; +// CPP-DECLTOP-NEXT: return [[VAL_2]]; +// CPP-DECLTOP-NEXT: } + +func.func @do_not_inline_cast_without_pure(%arg0: i32) -> f32 { + %0 = emitc.expression %arg0 : (i32) -> f32 { + %1 = cast %arg0 : i32 to f32 + yield %1 : f32 + } + return %0 : f32 +} + // CPP-DEFAULT: int32_t parentheses_for_same_precedence(int32_t [[VAL_1:v[0-9]+]], int32_t [[VAL_2:v[0-9]+]], int32_t [[VAL_3:v[0-9]+]]) { // CPP-DEFAULT-NEXT: return [[VAL_3]] / ([[VAL_1]] * [[VAL_2]]); // CPP-DEFAULT-NEXT: } From 5246dffd0e54a500db30249fe2e76343b7e9d187 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 10 Jul 2026 16:33:41 +1000 Subject: [PATCH 073/125] [orc-rt] Add a coding conventions doc (#208623) Add docs/CodingConventions.md, recording that ORC-RT follows the LLVM Coding Standards and describing the C API naming conventions. --- orc-rt/docs/CodingConventions.md | 61 ++++++++++++++++++++++++++++++++ orc-rt/docs/index.md | 1 + 2 files changed, 62 insertions(+) create mode 100644 orc-rt/docs/CodingConventions.md diff --git a/orc-rt/docs/CodingConventions.md b/orc-rt/docs/CodingConventions.md new file mode 100644 index 0000000000000..80dab8ad2fd2d --- /dev/null +++ b/orc-rt/docs/CodingConventions.md @@ -0,0 +1,61 @@ +# ORC-RT Coding Conventions + +## Overview + +ORC-RT is part of the LLVM project and generally follows the +[LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html), including +LLVM's naming conventions for C++ code: `PascalCase` for types, values, and +variables, and `camelBack` (lower-camelCase) for functions. + +This document records conventions that are specific to ORC-RT, or that need +restating because they are not obvious from the LLVM standards alone. Where this +document is silent, follow the LLVM Coding Standards. + +## C API naming + +The C API headers (under `include/orc-rt-c/`) cannot use C++ namespaces, so +namespacing is expressed through symbol-name prefixes, while the *casing* of +each name still follows the LLVM naming conventions used elsewhere in the +project. + +The rules are: + +- **`orc_rt_` is the top-level C namespace.** Every public C symbol begins with + it. +- **Nested namespaces are additional lower-case, underscore-separated + segments.** For example, `orc_rt_log_` is the nested namespace for the logging + API. +- **Types, values, and variables are `PascalCase`** (as in LLVM), appended to + their namespace prefix. +- **Functions are `camelBack`** (as in LLVM), appended to their namespace + prefix. +- **Enumerators are `PascalCase` values, scoped by prefixing them with their + enclosing type's name** (C has no scoped enums), joined with an underscore. +- **Macros are `UPPER_CASE`**, as in LLVM and C generally. + +A PascalCase type name may itself act as a scope for its "member" functions, +exactly like a nested namespace does; the two are indistinguishable in the +flattened C name, and both are spelled with a trailing underscore. + +### Examples + +| Symbol | Kind | +|-------------------------------|----------| +| `orc_rt_ErrorRef` | type | +| `orc_rt_Error_getTypeId` | function | +| `orc_rt_StringError_create` | function | +| `orc_rt_log_Category` | type | +| `orc_rt_log_Category_General` | value | +| `orc_rt_log_formatCheck` | function | +| `ORC_RT_LOG` | macro | + +Reading these: `orc_rt_Error_getTypeId` is the `getTypeId` function scoped to +the `Error` type; `orc_rt_log_formatCheck` is the `formatCheck` function in the +`log` namespace; and `orc_rt_log_Category_General` is the `General` value of the +`Category` type in the `log` namespace. + +## C++ code + +C++ code follows the LLVM Coding Standards directly: symbols live in real +namespaces (e.g. `orc_rt`), types/values/variables are `PascalCase`, functions +are `camelBack`, and macros are `UPPER_CASE`. diff --git a/orc-rt/docs/index.md b/orc-rt/docs/index.md index 56f9bb3829c17..b5fa45d77403e 100644 --- a/orc-rt/docs/index.md +++ b/orc-rt/docs/index.md @@ -9,6 +9,7 @@ The ORC runtime provides executor-side support code for the LLVM ORC APIs. :titlesonly: Building-orc-rt + CodingConventions ``` ### Current Status From 94b8fb92f78cbef24ff357d37db18b13d47749ad Mon Sep 17 00:00:00 2001 From: Urvi Rav <94829943+ravurvi20@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:08:31 +0530 Subject: [PATCH 074/125] [Flang][OpenMP] Added diagnostic for ORDERED THREADS SIMD inside plain SIMD region (#205723) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes [#205516 ](https://github.com/llvm/llvm-project/issues/205516) #### Problem Per OpenMP 4.5 Sec 2.13.8 Restrictions: > An ordered region arising from an ordered construct with both the simd and > threads clauses must be closely nested inside a loop SIMD region. Flang was missing this check. `!$OMP ORDERED THREADS SIMD` inside a standalone `!$OMP SIMD` region was accepted without diagnostic. #### Fix `check-omp-structure.cpp`: Added a new check in `ChecksOnOrderedAsBlock()`. If an ORDERED directive has both SIMD and THREADS clauses and is nested inside a standalone SIMD region (but not a DO SIMD region), emit the following error: `An ORDERED directive with SIMD and THREADS clauses must be closely nested in a worksharing-loop SIMD region.` `ordered02.f90`: Added two test cases: Negative test: ORDERED THREADS SIMD inside !$OMP SIMD → expected error. Positive test: ORDERED THREADS SIMD inside !$OMP DO SIMD ordered → no error, as allowed by OpenMP 2.13.8. --- flang/lib/Semantics/check-omp-structure.cpp | 7 ++++ flang/test/Semantics/OpenMP/ordered02.f90 | 36 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 02928401a382a..bb8145384d9ee 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -1673,6 +1673,13 @@ void OmpStructureChecker::ChecksOnOrderedAsBlock() { context_.Say(GetContext().directiveSource, "An ORDERED directive with SIMD clause must be closely nested in a " "SIMD or worksharing-loop SIMD region"_err_en_US); + } else if (CurrentDirectiveIsNested() && + FindClause(llvm::omp::Clause::OMPC_simd) && + FindClause(llvm::omp::Clause::OMPC_threads) && isNestedInSIMD && + !isNestedInDoSIMD) { + context_.Say(GetContext().directiveSource, + "An ORDERED directive with SIMD and THREADS clauses must be closely " + "nested in a worksharing-loop SIMD region"_err_en_US); } if (isNestedInDo && (noOrderedClause || isOrderedClauseWithPara)) { context_.Say(GetContext().directiveSource, diff --git a/flang/test/Semantics/OpenMP/ordered02.f90 b/flang/test/Semantics/OpenMP/ordered02.f90 index ed320c82a9794..649e008f7cb54 100644 --- a/flang/test/Semantics/OpenMP/ordered02.f90 +++ b/flang/test/Semantics/OpenMP/ordered02.f90 @@ -143,4 +143,40 @@ subroutine sub1() !$omp end ordered end do !$omp end target parallel do + + ! THREADS+SIMD inside a plain SIMD (not DO SIMD) region must be rejected + !$omp simd + do i = 1, N + !ERROR: An ORDERED directive with SIMD and THREADS clauses must be closely nested in a worksharing-loop SIMD region + !$omp ordered threads simd + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end simd + + ! THREADS+SIMD inside a DO SIMD region is valid + !$omp do simd ordered + do i = 1, N + !$omp ordered threads simd + arrayA(i) = foo(i) + !$omp end ordered + end do + !$omp end do simd end + +! No diagnostic when ORDERED THREADS SIMD is in a called routine (enclosing +! DO SIMD region is not visible to the static checker). +subroutine contains_ordered_threads_simd() + !$omp ordered threads simd + !$omp end ordered +end subroutine + +subroutine sub2() + integer :: i, N = 10 + external :: contains_ordered_threads_simd + !$omp do simd ordered + do i = 1, N + call contains_ordered_threads_simd() + end do + !$omp end do simd +end subroutine From b6a66701fae185048c88a04a4584b4f2de01b73a Mon Sep 17 00:00:00 2001 From: Akshat Dalal Date: Fri, 10 Jul 2026 12:22:46 +0530 Subject: [PATCH 075/125] [ImplicitNullChecks] Preserve debug location on FAULTING_OP (#205560) insertFaultingInstr() built the FAULTING_OP with an empty DebugLoc, dropping the folded memory op's source location. As a result, the faulting load is mislabeled in the line table, giving wrong source attribution for the very instruction that traps on a null deref. Fix by using MI->getDebugLoc(). The original report also flagged dropped MIFlags and def renamable/ sub-register/early-clobber bits, but those are not observable: Unpredictable is never set on loads, the register bits are never read (FAULTING_OP is opaque until AsmPrinter), and the sub-register write is already modeled correctly. Only the debug location is fixed here. --- llvm/lib/CodeGen/ImplicitNullChecks.cpp | 4 +-- .../X86/implicit-null-check-debugloc.ll | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll diff --git a/llvm/lib/CodeGen/ImplicitNullChecks.cpp b/llvm/lib/CodeGen/ImplicitNullChecks.cpp index c0f5bc81c9cf0..d06116a112c57 100644 --- a/llvm/lib/CodeGen/ImplicitNullChecks.cpp +++ b/llvm/lib/CodeGen/ImplicitNullChecks.cpp @@ -703,7 +703,6 @@ bool ImplicitNullChecks::analyzeBlockForNullChecks( /// faults. The FAULTING instruction is inserted at the end of MBB. MachineInstr *ImplicitNullChecks::insertFaultingInstr( MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *HandlerMBB) { - DebugLoc DL; unsigned NumDefs = MI->getDesc().getNumDefs(); assert(NumDefs <= 1 && "other cases unhandled!"); @@ -720,7 +719,8 @@ MachineInstr *ImplicitNullChecks::insertFaultingInstr( else FK = FaultMaps::FaultingStore; - auto MIB = BuildMI(MBB, DL, TII->get(TargetOpcode::FAULTING_OP), DefReg) + auto MIB = BuildMI(MBB, MI->getDebugLoc(), + TII->get(TargetOpcode::FAULTING_OP), DefReg) .addImm(FK) .addMBB(HandlerMBB) .addImm(MI->getOpcode()); diff --git a/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll b/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll new file mode 100644 index 0000000000000..8eadabcdd0bb7 --- /dev/null +++ b/llvm/test/CodeGen/X86/implicit-null-check-debugloc.ll @@ -0,0 +1,33 @@ +; RUN: llc -mtriple=x86_64-linux-gnu -enable-implicit-null-checks \ +; RUN: -stop-after=implicit-null-checks -o - %s | FileCheck %s + +; ImplicitNullChecks must preserve the folded load's debug location on the +; resulting FAULTING_OP, otherwise the faulting instruction loses its source +; attribution in the DWARF line table. + +; CHECK: [[LOC:![0-9]+]] = !DILocation(line: 4 +; CHECK: FAULTING_OP {{.*}}debug-location [[LOC]] :: (load (s32) from %ir.p) + +define i32 @f(ptr %p) !dbg !4 { +entry: + %nn = icmp eq ptr %p, null + br i1 %nn, label %null, label %notnull, !make.implicit !0 + +notnull: + %v = load i32, ptr %p, !dbg !7 + ret i32 %v + +null: + unreachable +} + +!llvm.dbg.cu = !{!1} +!llvm.module.flags = !{!2} + +!0 = !{} +!1 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, emissionKind: FullDebug) +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = !DIFile(filename: "repro.c", directory: "/") +!4 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !1) +!5 = !DISubroutineType(types: !{}) +!7 = !DILocation(line: 4, column: 10, scope: !4) From dac462d85cbc94ca5f5d9a78fc2cd01b8abaec92 Mon Sep 17 00:00:00 2001 From: aokblast Date: Fri, 10 Jul 2026 15:06:22 +0800 Subject: [PATCH 076/125] [BOLT] Fix use-old-text-zero-padding on FreeBSD (#206581) BSD od supports only decimal value to -N parameter. To fix the test failure, we use decimal value instead of hex value in this test case. --- bolt/test/AArch64/use-old-text-zero-padding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bolt/test/AArch64/use-old-text-zero-padding.c b/bolt/test/AArch64/use-old-text-zero-padding.c index 3c80c906eee36..3cd429fb2c24c 100644 --- a/bolt/test/AArch64/use-old-text-zero-padding.c +++ b/bolt/test/AArch64/use-old-text-zero-padding.c @@ -25,7 +25,7 @@ // RUN: llvm-readelf -S %t/test.bolt | awk '$3==".text"{print $6, $7}' \ // RUN: > %t/txt-loc // RUN: bash -c "read O S < %t/txt-loc; \ -// RUN: od -A x -t x1 -N 0x20 -j \$((0x\$O + 0x\$S)) %t/test.bolt" \ +// RUN: od -A x -t x1 -N 32 -j \$((0x\$O + 0x\$S)) %t/test.bolt" \ // RUN: | FileCheck %s --check-prefix=PADDING // PADDING: {{[0-9a-f]+}} 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 From eac699dd6068134486f2d3ca9ad72f7b0d2db384 Mon Sep 17 00:00:00 2001 From: David Green Date: Fri, 10 Jul 2026 08:07:02 +0100 Subject: [PATCH 077/125] [BOLT] Fix use-old-text-zero-padding on FreeBSD (#206581) (#208634) BSD od supports only decimal value to -N parameter. To fix the test failure, we use decimal value instead of hex value in this test case. Co-authored-by: aokblast From 8d590969badd9f3fed18a99fffbd9afdf3a975c6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 10 Jul 2026 09:09:08 +0200 Subject: [PATCH 078/125] [LLD][AArch64] Make adrp+ldr relaxation per-symbol all-or-nothing (#208396) We can't relax only some adrp+ldr pairs for a symbol, because there may be a branch target between the adrp and ldr of this form: adrp x1, :got:sym .Lfoo: ldr x1, [x1, :got_lo12:sym] # ... adrp x1, :got:sym ldr x2, [x1, :got_lo12:sym] b .Lfoo Relaxing the first adrp+ldr here would be invalid. This was clarified in the ARM ABI in: https://github.com/ARM-software/abi-aa/commit/11fb4ef42898060189d6a34ee96966e696ecbd20. The implementation already performed a pre-scan to check that the relevant relocations occur in pairs. Change this scan to a) check all the preconditions for the relaxation and b) make the decision per symbol. Fixes https://github.com/llvm/llvm-project/issues/138254. --- bolt/test/AArch64/got-load-symbolization.s | 11 ++- bolt/test/AArch64/lite-mode.s | 17 +++-- lld/ELF/Arch/AArch64.cpp | 83 +++++++++++++-------- lld/test/ELF/aarch64-adrp-ldr-got.s | 84 +++++++++++++++++++--- 4 files changed, 149 insertions(+), 46 deletions(-) diff --git a/bolt/test/AArch64/got-load-symbolization.s b/bolt/test/AArch64/got-load-symbolization.s index b4d6826887580..399859fd7bfd5 100644 --- a/bolt/test/AArch64/got-load-symbolization.s +++ b/bolt/test/AArch64/got-load-symbolization.s @@ -38,9 +38,9 @@ _start: # CHECK-NEXT: adrp x2, __BOLT_got_zero # CHECK-NEXT: nop # CHECK-NEXT: ldr x2, [x2, :lo12:__BOLT_got_zero{{.*}}] - adrp x2, :got:near + adrp x2, :got:near2 nop - ldr x2, [x2, :got_lo12:near] + ldr x2, [x2, :got_lo12:near2] ## Load data object with local visibility. Relaxable into adrp+add. # CHECK-NEXT: adrp x3, "local_far_data/1" @@ -58,6 +58,7 @@ _start: .size _start, .-_start .weak near +.weak near2 .weak far .weak far_data @@ -77,6 +78,12 @@ near: ret .size near, .-near + .globl near2 + .type near2, @function +near2: + ret +.size near2, .-near2 + #--- far.s .text diff --git a/bolt/test/AArch64/lite-mode.s b/bolt/test/AArch64/lite-mode.s index f2d06219f7a2d..24c31772b8475 100644 --- a/bolt/test/AArch64/lite-mode.s +++ b/bolt/test/AArch64/lite-mode.s @@ -24,12 +24,12 @@ # CHECK-COMPACT-NOT: <_start.org.0> ## Verify that the number of FDEs matches the number of functions in the output -## binary. There are three original functions and two optimized. +## binary. There are four original functions and three optimized. ## NOTE: at the moment we are emitting extra FDEs for patched functions, thus ## there is one more FDE for _start. # RUN: llvm-readelf -u %t.bolt | grep -wc FDE \ # RUN: | FileCheck --check-prefix=CHECK-FDE %s -# CHECK-FDE: 6 +# CHECK-FDE: 8 ## In lite mode, optimized code will be separated from the original .text by ## over 128MB, making it impossible for call/bl instructions in cold functions @@ -106,9 +106,9 @@ cold_function: # CHECK-NEXT: add x4 ## Check that non-relaxable GOT load is left intact. - adrp x5, :got:far_func + adrp x5, :got:far_func2 nop - ldr x5, [x5, #:got_lo12:far_func] + ldr x5, [x5, #:got_lo12:far_func2] # CHECK-INPUT-NEXT: adrp x5 # CHECK-INPUT-NEXT: nop # CHECK-INPUT-NEXT: ldr x5 @@ -155,3 +155,12 @@ far_func: ret x30 .cfi_endproc .size far_func, .-far_func + + .globl far_func2 + .type far_func2, %function +far_func2: +# FDATA: 0 [unknown] 0 1 far_func2 0 0 100 + .cfi_startproc + ret x30 + .cfi_endproc + .size far_func2, .-far_func2 diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp index ed6d42fd4c05e..11c3dca1a358a 100644 --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -106,13 +106,17 @@ class AArch64 : public TargetInfo { struct AArch64Relaxer { Ctx &ctx; - bool safeToRelaxAdrpLdr = false; + SmallPtrSet unsafeToRelaxAdrpLdr; - AArch64Relaxer(Ctx &ctx, ArrayRef relocs); + AArch64Relaxer(Ctx &ctx, ArrayRef relocs, uint64_t secAddr, + uint8_t *buf); bool tryRelaxAdrpAdd(const Relocation &adrpRel, const Relocation &addRel, uint64_t secAddr, uint8_t *buf) const; bool tryRelaxAdrpLdr(const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, uint8_t *buf) const; + bool isLegalAdrpLdrRelaxationCandidate(const Relocation &adrpRel, + const Relocation &ldrRel, + uint64_t secAddr, uint8_t *buf) const; }; } // namespace @@ -896,26 +900,30 @@ void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, llvm_unreachable("invalid relocation for TLS IE to LE relaxation"); } -AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs) +AArch64Relaxer::AArch64Relaxer(Ctx &ctx, ArrayRef relocs, + uint64_t secAddr, uint8_t *buf) : ctx(ctx) { if (!ctx.arg.relax) return; - // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC - // always appear in pairs. + // For a given symbol R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC + // relaxation is all-or-nothing. We can't relax only some of them, as there + // may be a jump destination between the two relocations. size_t i = 0; const size_t size = relocs.size(); for (; i != size; ++i) { if (relocs[i].type == R_AARCH64_ADR_GOT_PAGE) { - if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC) { + if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC && + !unsafeToRelaxAdrpLdr.contains(relocs[i].sym) && + isLegalAdrpLdrRelaxationCandidate(relocs[i], relocs[i + 1], secAddr, + buf)) { ++i; continue; } - break; + unsafeToRelaxAdrpLdr.insert(relocs[i].sym); } else if (relocs[i].type == R_AARCH64_LD64_GOT_LO12_NC) { - break; + unsafeToRelaxAdrpLdr.insert(relocs[i].sym); } } - safeToRelaxAdrpLdr = i == size; } bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, @@ -966,23 +974,9 @@ bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, return true; } -bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, - const Relocation &ldrRel, uint64_t secAddr, - uint8_t *buf) const { - if (!safeToRelaxAdrpLdr) - return false; - - // When the definition of sym is not preemptible then we may - // be able to relax - // ADRP xn, :got: sym - // LDR xn, [ xn :got_lo12: sym] - // to - // ADRP xn, sym - // ADD xn, xn, :lo_12: sym - - if (adrpRel.type != R_AARCH64_ADR_GOT_PAGE || - ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) - return false; +bool AArch64Relaxer::isLegalAdrpLdrRelaxationCandidate( + const Relocation &adrpRel, const Relocation &ldrRel, uint64_t secAddr, + uint8_t *buf) const { // Check if the relocations apply to consecutive instructions. if (adrpRel.offset + 4 != ldrRel.offset) return false; @@ -1022,10 +1016,37 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, if (val != llvm::SignExtend64(val, 33)) return false; + return true; +} + +bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, + const Relocation &ldrRel, uint64_t secAddr, + uint8_t *buf) const { + // When the definition of sym is not preemptible then we may + // be able to relax + // ADRP xn, :got: sym + // LDR xn, [ xn :got_lo12: sym] + // to + // ADRP xn, sym + // ADD xn, xn, :lo_12: sym + + if (!ctx.arg.relax || adrpRel.type != R_AARCH64_ADR_GOT_PAGE || + ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) + return false; + + Symbol *sym = adrpRel.sym; + if (unsafeToRelaxAdrpLdr.contains(sym)) + return false; + + assert(isLegalAdrpLdrRelaxationCandidate(adrpRel, ldrRel, secAddr, buf) && + "Should have been marked as unsafe"); + + uint32_t adrpInstr = read32le(buf + adrpRel.offset); + uint32_t adrpDestReg = adrpInstr & 0x1f; Relocation adrpSymRel = {RE_AARCH64_PAGE_PC, R_AARCH64_ADR_PREL_PG_HI21, - adrpRel.offset, /*addend=*/0, &sym}; + adrpRel.offset, /*addend=*/0, sym}; Relocation addRel = {R_ABS, R_AARCH64_ADD_ABS_LO12_NC, ldrRel.offset, - /*addend=*/0, &sym}; + /*addend=*/0, sym}; // adrp x_ write32le(buf + adrpSymRel.offset, 0x90000000 | adrpDestReg); @@ -1034,11 +1055,11 @@ bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, ctx.target->relocate( buf + adrpSymRel.offset, adrpSymRel, - SignExtend64(getAArch64Page(sym.getVA(ctx)) - + SignExtend64(getAArch64Page(sym->getVA(ctx)) - getAArch64Page(secAddr + adrpSymRel.offset), 64)); ctx.target->relocate(buf + addRel.offset, addRel, - SignExtend64(sym.getVA(ctx), 64)); + SignExtend64(sym->getVA(ctx), 64)); tryRelaxAdrpAdd(adrpSymRel, addRel, secAddr, buf); return true; } @@ -1052,7 +1073,7 @@ static bool needsGotForMemtag(const Relocation &rel) { void AArch64::relocateAlloc(InputSection &sec, uint8_t *buf) const { uint64_t secAddr = sec.getOutputSection()->addr + sec.outSecOff; const ArrayRef relocs = sec.relocs(); - AArch64Relaxer relaxer(ctx, relocs); + AArch64Relaxer relaxer(ctx, relocs, secAddr, buf); for (size_t i = 0, size = relocs.size(); i != size; ++i) { const Relocation &rel = relocs[i]; if (rel.expr == R_NONE) // See finalizeAddressDependentContent() diff --git a/lld/test/ELF/aarch64-adrp-ldr-got.s b/lld/test/ELF/aarch64-adrp-ldr-got.s index 56a90aac3876c..a8216da9f20c3 100644 --- a/lld/test/ELF/aarch64-adrp-ldr-got.s +++ b/lld/test/ELF/aarch64-adrp-ldr-got.s @@ -4,6 +4,7 @@ # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/a.s -o %t/a.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/unpaired.s -o %t/unpaired.o # RUN: llvm-mc -filetype=obj -triple=aarch64 %t/lone-ldr.s -o %t/lone-ldr.o +# RUN: llvm-mc -filetype=obj -triple=aarch64 %t/all-or-nothing.s -o %t/all-or-nothing.o # RUN: ld.lld %t/a.o -T %t/out-of-adr-range.t -o %t/a # RUN: llvm-objdump --no-show-raw-insn -d %t/a | FileCheck %s @@ -49,7 +50,8 @@ # RUN: llvm-objdump --no-show-raw-insn -d %t/out-of-range | \ # RUN: FileCheck --check-prefix=X1-NO-RELAX %s -## Relocations do not appear in pairs, no relaxations should be applied. +## Relocations do not appear in pairs, no relaxations should be applied for +## that symbol. We can still relax other symbols. # RUN: ld.lld %t/unpaired.o -o %t/unpaired # RUN: llvm-objdump --no-show-raw-insn -d %t/unpaired | \ # RUN: FileCheck --check-prefix=UNPAIRED %s @@ -58,6 +60,9 @@ # UNPAIRED-NEXT: b # UNPAIRED-NEXT: adrp x0 # UNPAIRED: ldr x0 +## This is a different symbol. +# UNPAIRED: nop +# UNPAIRED: adr x1 ## Relocations do not appear in pairs, no relaxations should be applied. # RUN: ld.lld %t/lone-ldr.o -o %t/lone-ldr @@ -66,6 +71,26 @@ # LONE-LDR: ldr x0 +## Make sure that relaxation is not applied if not all adrp+ldr pairs for +## a given symbol can be relaxed. This is not legal, because there may be +## a branch destination between the adrp and ldr instructions. We can still +## perform the relaxation for other symbols, or the same symbol in a different +## section. +# RUN: ld.lld %t/all-or-nothing.o -o %t/all-or-nothing +# RUN: llvm-objdump --no-show-raw-insn -d %t/all-or-nothing | \ +# RUN: FileCheck --check-prefix=ALL-OR-NOTHING %s + +# ALL-OR-NOTHING-LABEL: <_start>: +# ALL-OR-NOTHING: adrp x1 +# ALL-OR-NOTHING: ldr x1 +# ALL-OR-NOTHING: adrp x1 +# ALL-OR-NOTHING: ldr x2 +# ALL-OR-NOTHING: nop +# ALL-OR-NOTHING: adr x1 +# ALL-OR-NOTHING-LABEL: : +# ALL-OR-NOTHING: nop +# ALL-OR-NOTHING: adr x1 + ## This linker script ensures that .rodata and .text are sufficiently (>1M) ## far apart so that the adrp + ldr pair cannot be relaxed to adr + nop. #--- out-of-adr-range.t @@ -95,25 +120,40 @@ SECTIONS { .hidden x x: .word 10 +.hidden y +y: +.word 10 +.hidden z +z: +.word 10 +.hidden u +u: +.word 10 +.hidden v +v: +.word 10 .text .global _start _start: adrp x1, :got:x ldr x1, [x1, #:got_lo12:x] - adrp x2, :got:x+1 - ldr x2, [x2, #:got_lo12:x] - adrp x3, :got:x - ldr x3, [x3, #:got_lo12:x+8] - adrp x4, :got:x - ldr x5, [x4, #:got_lo12:x] - adrp x6, :got:x - ldr x6, [x0, #:got_lo12:x] + adrp x2, :got:y+1 + ldr x2, [x2, #:got_lo12:y] + adrp x3, :got:z + ldr x3, [x3, #:got_lo12:z+8] + adrp x4, :got:u + ldr x5, [x4, #:got_lo12:u] + adrp x6, :got:v + ldr x6, [x0, #:got_lo12:v] #--- unpaired.s .text .hidden x x: nop +.hidden y +y: + nop .global _start _start: adrp x0, :got:x @@ -121,6 +161,8 @@ _start: adrp x0, :got:x L: ldr x0, [x0, #:got_lo12:x] + adrp x1, :got:y + ldr x1, [x1, #:got_lo12:y] #--- lone-ldr.s .text @@ -130,3 +172,27 @@ x: .global _start _start: ldr x0, [x0, #:got_lo12:x] + +#--- all-or-nothing.s +.rodata +.hidden x +x: +.word 10 +.hidden y +y: +.word 10 +.text +.global _start +_start: + adrp x1, :got:x + ldr x1, [x1, #:got_lo12:x] + adrp x1, :got:x + ldr x2, [x1, #:got_lo12:x] + adrp x1, :got:y + ldr x1, [x1, #:got_lo12:y] + +.section .text.foo +.global foo +foo: + adrp x1, :got:x + ldr x1, [x1, #:got_lo12:x] From 9c4e4b1f8781808d07f86aa4fb726dbb9a477bad Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Jul 2026 09:20:01 +0200 Subject: [PATCH 079/125] AMDGPU: Migrate unittests to subarch triples (#206486) Replace specifying a processor name with the triple subarch. The register-limit helpers in AMDGPUUnitTests.cpp that enumerate every valid CPU via fillValidArchListAMDGCN still pass the CPU explicitly, as does the MC Disassembler smoke test (its C disassembler API derives the subtarget from the CPU, not the triple subarch). Co-authored-by: Claude (Opus 4.8) --- llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp | 6 +++--- llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp | 4 ++-- llvm/unittests/CodeGen/RematerializerTest.cpp | 2 +- llvm/unittests/MC/AMDGPU/Disassembler.cpp | 4 ++-- llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp | 12 ++++++------ llvm/unittests/MI/LiveIntervalTest.cpp | 4 ++-- llvm/unittests/MIR/MachineMetadata.cpp | 4 ++-- llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp | 2 +- llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp | 4 ++-- llvm/unittests/Target/AMDGPU/CSETest.cpp | 2 +- llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp | 12 ++++++------ .../Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp | 2 +- llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp | 2 +- llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp | 2 +- llvm/unittests/Target/AMDGPU/PALMetadata.cpp | 2 +- .../Target/AMDGPU/UniformityAnalysisTest.cpp | 2 +- 16 files changed, 33 insertions(+), 33 deletions(-) diff --git a/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp b/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp index 7f53f5322f548..08a32390140d6 100644 --- a/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp +++ b/llvm/unittests/CodeGen/AMDGPUMetadataTest.cpp @@ -52,14 +52,14 @@ class AMDGPUSelectionDAGTest : public testing::Test { void SetUp() override { std::string Error; - Triple TargetTriple("amdgcn--amdpal"); + Triple TargetTriple("amdgpu10.10--amdpal"); const Target *T = TargetRegistry::lookupTarget(TargetTriple, Error); if (!T) GTEST_SKIP(); TargetOptions Options; - TM = std::unique_ptr(T->createTargetMachine( - TargetTriple, "gfx1010", "", Options, std::nullopt)); + TM = std::unique_ptr( + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt)); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp index 19b3161dd0313..da3714a620b90 100644 --- a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.cpp @@ -67,7 +67,7 @@ body: | } std::unique_ptr AMDGPUGISelMITest::createTargetMachine() const { - Triple TargetTriple("amdgcn-amd-amdhsa"); + Triple TargetTriple("amdgpu9.00-amd-amdhsa"); std::string Error; const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); if (!T) @@ -75,7 +75,7 @@ std::unique_ptr AMDGPUGISelMITest::createTargetMachine() const { TargetOptions Options; return std::unique_ptr( - T->createTargetMachine(TargetTriple, "gfx900", "", Options, std::nullopt, + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt, std::nullopt, CodeGenOptLevel::Aggressive)); } diff --git a/llvm/unittests/CodeGen/RematerializerTest.cpp b/llvm/unittests/CodeGen/RematerializerTest.cpp index b29f06ca83892..b37760a57580e 100644 --- a/llvm/unittests/CodeGen/RematerializerTest.cpp +++ b/llvm/unittests/CodeGen/RematerializerTest.cpp @@ -102,7 +102,7 @@ class RematerializerTest : public CodeGenTestBase { #endif } - void SetUp() override { setUpImpl("amdgcn--", "gfx950", ""); } + void SetUp() override { setUpImpl("amdgpu9.50--", "", ""); } using RematerializerTestFn = std::function; diff --git a/llvm/unittests/MC/AMDGPU/Disassembler.cpp b/llvm/unittests/MC/AMDGPU/Disassembler.cpp index a6c4b98915aca..c0017f79427cc 100644 --- a/llvm/unittests/MC/AMDGPU/Disassembler.cpp +++ b/llvm/unittests/MC/AMDGPU/Disassembler.cpp @@ -32,8 +32,8 @@ static const char *symbolLookupCallback(void *DisInfo, uint64_t ReferenceValue, return nullptr; } -static constexpr char TripleName[] = "amdgcn--amdpal"; -static constexpr char CPUName[] = "gfx1030"; +static constexpr char TripleName[] = "amdgpu10.30--amdpal"; +static constexpr char CPUName[] = ""; // Basic smoke test. TEST(AMDGPUDisassembler, Basic) { diff --git a/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp b/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp index 4edd0f1227378..2123eefed347a 100644 --- a/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp +++ b/llvm/unittests/MC/AMDGPU/DwarfRegMappings.cpp @@ -43,9 +43,9 @@ createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) { } TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createTargetMachine(Triple, "gfx1010", "+wavefrontsize64"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createTargetMachine(Triple, "", "+wavefrontsize64"); if (TM) { const auto &MRI = TM->getMCRegisterInfo(); // Wave64 Dwarf register mapping test numbers @@ -63,9 +63,9 @@ TEST(AMDGPUDwarfRegMappingTests, TestWave64DwarfRegMapping) { } TEST(AMDGPUDwarfRegMappingTests, TestWave32DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createTargetMachine(Triple, "gfx1010", "+wavefrontsize32"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createTargetMachine(Triple, "", "+wavefrontsize32"); if (TM) { const auto &MRI = TM->getMCRegisterInfo(); // Wave32 Dwarf register mapping test numbers diff --git a/llvm/unittests/MI/LiveIntervalTest.cpp b/llvm/unittests/MI/LiveIntervalTest.cpp index 45b8aeb72b598..0581d84fd0709 100644 --- a/llvm/unittests/MI/LiveIntervalTest.cpp +++ b/llvm/unittests/MI/LiveIntervalTest.cpp @@ -42,7 +42,7 @@ void initLLVM() { /// unittests, we go for "AMDGPU" to be able to test normal and subregister /// liveranges. std::unique_ptr createTargetMachine() { - Triple TargetTriple("amdgcn--"); + Triple TargetTriple("amdgpu9.00--"); std::string Error; const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); if (!T) @@ -50,7 +50,7 @@ std::unique_ptr createTargetMachine() { TargetOptions Options; return std::unique_ptr( - T->createTargetMachine(TargetTriple, "gfx900", "", Options, std::nullopt, + T->createTargetMachine(TargetTriple, "", "", Options, std::nullopt, std::nullopt, CodeGenOptLevel::Aggressive)); } diff --git a/llvm/unittests/MIR/MachineMetadata.cpp b/llvm/unittests/MIR/MachineMetadata.cpp index 8960a3a107d10..f58a3cac1bb0f 100644 --- a/llvm/unittests/MIR/MachineMetadata.cpp +++ b/llvm/unittests/MIR/MachineMetadata.cpp @@ -441,8 +441,8 @@ CHECK: %1:gr32 = MOV32rm %0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.p, !al } TEST_F(MachineMetadataTest, MMSlotTrackerAMDGPU) { - auto TM = createTargetMachine(Triple::normalize("amdgcn-amd-amdhsa"), - "gfx1010", ""); + auto TM = + createTargetMachine(Triple::normalize("amdgpu10.10-amd-amdhsa"), "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp b/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp index 86c296feed792..83b47531a96fb 100644 --- a/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp +++ b/llvm/unittests/Target/AMDGPU/AMDGPUMCExprTest.cpp @@ -31,7 +31,7 @@ class AMDGPUMCExprTest : public AMDGPUTestBase { AMDGPUMCExprTest() { - TM = createAMDGPUTargetMachine("amdgcn--amdpal", "gfx1010", ""); + TM = createAMDGPUTargetMachine("amdgpu10.10--amdpal", "", ""); LLVMCtx = std::make_unique(); M = std::make_unique("Module", *LLVMCtx); diff --git a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp index d1570e3986188..9bb526e7c85f5 100644 --- a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp +++ b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp @@ -275,7 +275,7 @@ static const char *printSubReg(const TargetRegisterInfo &TRI, unsigned SubReg) { } TEST_F(AMDGPUTestBase, TestReverseComposeSubRegIndices) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx900", ""); + auto TM = createAMDGPUTargetMachine("amdgpu9.00-amd-", "", ""); if (!TM) return; GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), @@ -352,7 +352,7 @@ TEST_F(AMDGPUTestBase, TestReverseComposeSubRegIndices) { TEST_F(AMDGPUTestBase, TestGetNamedOperandIdx) { std::unique_ptr TM = - createAMDGPUTargetMachine("amdgcn-amd-", "gfx900", ""); + createAMDGPUTargetMachine("amdgpu9.00-amd-", "", ""); if (!TM) return; const MCInstrInfo *MCII = TM->getMCInstrInfo(); diff --git a/llvm/unittests/Target/AMDGPU/CSETest.cpp b/llvm/unittests/Target/AMDGPU/CSETest.cpp index 382f23906e92d..a302a3e372d45 100644 --- a/llvm/unittests/Target/AMDGPU/CSETest.cpp +++ b/llvm/unittests/Target/AMDGPU/CSETest.cpp @@ -16,7 +16,7 @@ using namespace llvm; TEST_F(AMDGPUTestBase, TestCSEForRegisterClassOrBankAndLLT) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx1100", ""); + auto TM = createAMDGPUTargetMachine("amdgpu11.00-amd-", "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp b/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp index ec8ed7f15b35a..fe3cafe270fbe 100644 --- a/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp +++ b/llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp @@ -13,9 +13,9 @@ using namespace llvm; TEST_F(AMDGPUTestBase, TestWave64DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createAMDGPUTargetMachine(Triple, "gfx1010", "+wavefrontsize64"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createAMDGPUTargetMachine(Triple, "", "+wavefrontsize64"); if (TM) { GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), std::string(TM->getTargetFeatureString()), *TM); @@ -53,9 +53,9 @@ TEST_F(AMDGPUTestBase, TestWave64DwarfRegMapping) { } TEST_F(AMDGPUTestBase, TestWave32DwarfRegMapping) { - for (auto Triple : - {"amdgcn-amd-", "amdgcn-amd-amdhsa", "amdgcn-amd-amdpal"}) { - auto TM = createAMDGPUTargetMachine(Triple, "gfx1010", "+wavefrontsize32"); + for (auto Triple : {"amdgpu10.10-amd-", "amdgpu10.10-amd-amdhsa", + "amdgpu10.10-amd-amdpal"}) { + auto TM = createAMDGPUTargetMachine(Triple, "", "+wavefrontsize32"); if (TM) { GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), std::string(TM->getTargetFeatureString()), *TM); diff --git a/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp b/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp index 8034bf6561d86..4f02ab9e482a3 100644 --- a/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp +++ b/llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp @@ -14,7 +14,7 @@ using namespace llvm; TEST_F(AMDGPUTestBase, ExecMayBeModifiedBeforeAnyUse) { - auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx906", ""); + auto TM = createAMDGPUTargetMachine("amdgpu9.06-amd-", "", ""); if (!TM) GTEST_SKIP(); diff --git a/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp index d907ee269a448..c0acf9e7dde4f 100644 --- a/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp +++ b/llvm/unittests/Target/AMDGPU/GCNRegPressureTest.cpp @@ -22,7 +22,7 @@ using namespace llvm; class GCNRegPressureTest : public llvm::CodeGenTestBase { public: - void SetUp() override { setUpImpl("amdgcn--", "gfx908", ""); } + void SetUp() override { setUpImpl("amdgpu9.08--", "", ""); } }; TEST_F(GCNRegPressureTest, DownwardTrackerEndOnDbgVal) { diff --git a/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp b/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp index ec3d465891467..0cd41faf6e5ad 100644 --- a/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp +++ b/llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp @@ -18,7 +18,7 @@ using namespace llvm; class LiveRegUnitsTest : public AMDGPUCodeGenTestBase { public: - void SetUp() override { setUpImpl("amdgcn-amd-", "gfx1200", ""); } + void SetUp() override { setUpImpl("amdgpu12.00-amd-", "", ""); } }; TEST_F(LiveRegUnitsTest, TestVGPRBlockLoadStore) { diff --git a/llvm/unittests/Target/AMDGPU/PALMetadata.cpp b/llvm/unittests/Target/AMDGPU/PALMetadata.cpp index 64537921ec4a6..38d3f8b37cce2 100644 --- a/llvm/unittests/Target/AMDGPU/PALMetadata.cpp +++ b/llvm/unittests/Target/AMDGPU/PALMetadata.cpp @@ -34,7 +34,7 @@ class PALMetadata : public AMDGPUTestBase { AMDGPUPALMetadata MD; PALMetadata() { - TM = createAMDGPUTargetMachine("amdgcn--amdpal", "gfx1010", ""); + TM = createAMDGPUTargetMachine("amdgpu10.10--amdpal", "", ""); Ctx = std::make_unique(); M = std::make_unique("Module", *Ctx); diff --git a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp index e61ef1d56c0a3..5b98e34c2a91e 100644 --- a/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp +++ b/llvm/unittests/Target/AMDGPU/UniformityAnalysisTest.cpp @@ -55,7 +55,7 @@ TEST_F(AMDGPUTestBase, NewValueIsConservativelyDivergent) { ASSERT_TRUE(F); auto TM = - createAMDGPUTargetMachine("amdgcn-amd-", "gfx1010", "+wavefrontsize32"); + createAMDGPUTargetMachine("amdgpu10.10-amd-", "", "+wavefrontsize32"); ASSERT_TRUE(TM); TargetTransformInfo TTI = TM->getTargetTransformInfo(*F); From b5a27b48e5d7dba706911047fa1c5692be44d10e Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Jul 2026 09:22:57 +0200 Subject: [PATCH 080/125] AMDGPU: Rewrite target-cpu test for new subarches (#206485) The function subtargets should now be a valid subtarget for the top-level subarch. --- llvm/test/CodeGen/AMDGPU/target-cpu.ll | 116 ++++++++++--------------- 1 file changed, 47 insertions(+), 69 deletions(-) diff --git a/llvm/test/CodeGen/AMDGPU/target-cpu.ll b/llvm/test/CodeGen/AMDGPU/target-cpu.ll index 2e6a3aee4be63..994319756db77 100644 --- a/llvm/test/CodeGen/AMDGPU/target-cpu.ll +++ b/llvm/test/CodeGen/AMDGPU/target-cpu.ll @@ -1,80 +1,58 @@ -; RUN: llc -mtriple=amdgcn -mcpu=gfx600 -disable-promote-alloca-to-vector < %s | FileCheck %s - -declare ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() #1 - -declare i32 @llvm.amdgcn.workitem.id.x() #1 - -; CI+ intrinsic -declare void @llvm.amdgcn.s.dcache.inv.vol() #0 - -; VI+ intrinsic -declare void @llvm.amdgcn.s.dcache.wb() #0 +; RUN: llc -mtriple=amdgpu9 < %s | FileCheck %s +; The default gfx9-generic subtarget lacks the mad-mix instructions, so the +; f16 multiply-add is expanded to conversions plus a separate fma. ; CHECK-LABEL: {{^}}target_none: -; CHECK: s_movk_i32 [[OFFSETREG:s[0-9]+]], 0x400 -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, [[OFFSETREG]] -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -define amdgpu_kernel void @target_none() #0 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - ret void +; CHECK: v_cvt_f32_f16_e32 [[A:v[0-9]+]], v0 +; CHECK: v_cvt_f32_f16_e32 [[B:v[0-9]+]], v1 +; CHECK: v_cvt_f32_f16_e32 [[C:v[0-9]+]], v2 +; CHECK: v_mac_f32_e32 [[C]], [[A]], [[B]] +define float @target_none(half %a, half %b, half %c) #1 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_tahiti: -; CHECK: s_movk_i32 [[OFFSETREG:s[0-9]+]], 0x400 -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, [[OFFSETREG]] -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -define amdgpu_kernel void @target_tahiti() #1 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - ret void +; gfx900 has the mad-mix instructions, so the same multiply-add folds the f16 +; conversions into a single v_mad_mix_f32. +; CHECK-LABEL: {{^}}target_gfx900: +; CHECK: v_mad_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1] +define float @target_gfx900(half %a, half %b, half %c) #2 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_bonaire: -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0x100 -; CHECK: buffer_store_dword v{{[0-9]+}}, v{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0 addr64 -; CHECK: s_dcache_inv_vol -define amdgpu_kernel void @target_bonaire() #3 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - call void @llvm.amdgcn.s.dcache.inv.vol() - ret void +; gfx906 has the fma-mix instructions, so the same multiply-add folds the f16 +; conversions into a single v_fma_mix_f32. +; CHECK-LABEL: {{^}}target_gfx906_mad_mix: +; CHECK: v_fma_mix_f32 v0, v0, v1, v2 op_sel_hi:[1,1,1] +define float @target_gfx906_mad_mix(half %a, half %b, half %c) #4 { + %ae = fpext half %a to float + %be = fpext half %b to float + %ce = fpext half %c to float + %r = call float @llvm.fmuladd.f32(float %ae, float %be, float %ce) + ret float %r } -; CHECK-LABEL: {{^}}target_fiji: -; CHECK: s_load_dwordx2 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, 0x400 -; CHECK: flat_store_dword -; CHECK: s_dcache_wb{{$}} -define amdgpu_kernel void @target_fiji() #4 { - %kernargs = call ptr addrspace(4) @llvm.amdgcn.kernarg.segment.ptr() - %kernargs.gep = getelementptr inbounds i8, ptr addrspace(4) %kernargs, i64 1024 - %ptr = load ptr addrspace(1), ptr addrspace(4) %kernargs.gep - %id = call i32 @llvm.amdgcn.workitem.id.x() - %id.ext = sext i32 %id to i64 - %gep = getelementptr inbounds i32, ptr addrspace(1) %ptr, i64 %id.ext - store i32 0, ptr addrspace(1) %gep - call void @llvm.amdgcn.s.dcache.wb() +; The fdot2 intrinsic is only available on gfx906. +; CHECK-LABEL: {{^}}target_gfx906: +; CHECK: v_dot2_f32_f16 +define amdgpu_kernel void @target_gfx906(ptr addrspace(1) %out, <2 x half> %a, <2 x half> %b, float %c) #3 { + %dot = call float @llvm.amdgcn.fdot2(<2 x half> %a, <2 x half> %b, float %c, i1 false) + store float %dot, ptr addrspace(1) %out, align 4 ret void } -attributes #0 = { nounwind } -attributes #1 = { nounwind readnone } -attributes #2 = { nounwind "target-cpu"="tahiti" } -attributes #3 = { nounwind "target-cpu"="bonaire" } -attributes #4 = { nounwind "target-cpu"="fiji" } -attributes #5 = { nounwind "amdgpu-waves-per-eu"="1,3" "amdgpu-flat-work-group-size"="1,256" } +declare float @llvm.fmuladd.f32(float, float, float) #0 +declare float @llvm.amdgcn.fdot2(<2 x half>, <2 x half>, float, i1 immarg) #0 + +attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } +attributes #1 = { nounwind denormal_fpenv(float: preservesign) } +attributes #2 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx900" } +attributes #3 = { nounwind "target-cpu"="gfx906" } +attributes #4 = { nounwind denormal_fpenv(float: preservesign) "target-cpu"="gfx906" } From 1cc5d2cf0faba66b30d9a68735006ed3e9742fc7 Mon Sep 17 00:00:00 2001 From: firmiana402 Date: Fri, 10 Jul 2026 15:39:52 +0800 Subject: [PATCH 081/125] [lldb] Fix DW_OP_convert type handling (#208435) This PR fixes #208197 A nonzero DW_OP_convert operand must reference a DW_TAG_base_type DIE. LLDB previously accepted any DIE that happened to carry base-type-like size and encoding attributes. This patch rejects non-base-type DIEs before using them as DW_OP_convert target types. ## Tests Extended DWARFExpression.DW_OP_convert coverage to verify: - non-DW_TAG_base_type DIEs are rejected as DW_OP_convert target types; --- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 3 +++ .../Expression/DWARFExpressionTest.cpp | 22 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 4b02124e987e8..aea2267277656 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -724,6 +724,9 @@ DWARFUnit::GetDIEBitSizeAndSign(uint64_t relative_die_offset) const { DWARFDIE die = const_cast(this)->GetDIE(abs_die_offset); if (!die) return llvm::createStringError("cannot resolve DW_OP_convert type DIE"); + if (die.Tag() != DW_TAG_base_type) + return llvm::createStringError( + "DW_OP_convert type DIE is not a DW_TAG_base_type"); uint64_t encoding = die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user); uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index 042045f35552c..f552f42dcba5c 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -445,6 +445,14 @@ TEST(DWARFExpression, DW_OP_convert) { Form: DW_FORM_data1 - Attribute: DW_AT_byte_size Form: DW_FORM_data1 + - Code: 0x00000003 + Tag: DW_TAG_enumeration_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 debug_info: - Version: 4 AddrSize: 8 @@ -493,15 +501,21 @@ TEST(DWARFExpression, DW_OP_convert) { Values: - Value: 0x000000000000000b # DW_ATE_numeric_string - Value: 0x0000000000000001 + # 0x00000020: + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000007 # DW_ATE_unsigned + - Value: 0x0000000000000004 - AbbrCode: 0x00000000 )"; - // Compile unit relative offsets to each DW_TAG_base_type + // Compile unit relative offsets to type DIEs. uint8_t offs_uint32_t = 0x0000000e; uint8_t offs_uint64_t = 0x00000011; uint8_t offs_sint64_t = 0x00000014; uint8_t offs_uchar = 0x00000017; uint8_t offs_schar = 0x0000001a; + uint8_t offs_enum = 0x00000020; DWARFExpressionTester t(yamldata, /*cu_index=*/1); ASSERT_TRUE((bool)t.GetDwarfUnit()); @@ -575,6 +589,12 @@ TEST(DWARFExpression, DW_OP_convert) { t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(), llvm::Failed()); + // Not a DW_TAG_base_type. + EXPECT_THAT_ERROR( + t.Eval({DW_OP_const1s, 'X', DW_OP_convert, offs_enum}).takeError(), + llvm::FailedWithMessage( + "DW_OP_convert type DIE is not a DW_TAG_base_type")); + // A non-zero DIE offset with no DWARF unit. EXPECT_THAT_ERROR( Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01}, nullptr, nullptr) From 3595454d79c9bc4253f70961e32516e23805b982 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Jul 2026 09:49:14 +0200 Subject: [PATCH 082/125] MC: Start some error messages with a lowercase (#208570) Also add a missing test for one of them. --- llvm/lib/MC/ELFObjectWriter.cpp | 2 +- llvm/lib/MC/MachObjectWriter.cpp | 2 +- llvm/test/MC/ELF/size-expression-must-be-absolute.s | 6 ++++++ llvm/test/MC/X86/check-end-of-data-region.s | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 llvm/test/MC/ELF/size-expression-must-be-absolute.s diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f47bfdee42c62..3af4851d39d94 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -457,7 +457,7 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, if (ESize) { int64_t Res; if (!ESize->evaluateKnownAbsolute(Res, Asm)) - report_fatal_error("Size expression must be absolute."); + report_fatal_error("size expression must be absolute"); Size = Res; } diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index b42155d18bf0a..e274d886c22d8 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -1060,7 +1060,7 @@ uint64_t MachObjectWriter::writeObject() { if (Data.End) End = getSymbolAddress(*Data.End); else - report_fatal_error("Data region not terminated"); + report_fatal_error("data region not terminated"); LLVM_DEBUG(dbgs() << "data in code region-- kind: " << Data.Kind << " start: " << Start << "(" << Data.Start->getName() diff --git a/llvm/test/MC/ELF/size-expression-must-be-absolute.s b/llvm/test/MC/ELF/size-expression-must-be-absolute.s new file mode 100644 index 0000000000000..769df52d9bb44 --- /dev/null +++ b/llvm/test/MC/ELF/size-expression-must-be-absolute.s @@ -0,0 +1,6 @@ +// RUN: not --crash llvm-mc -triple=x86_64 -filetype=obj -o /dev/null %s 2>&1 | FileCheck %s + +a: b: +.size a, b + +// CHECK: LLVM ERROR: size expression must be absolute diff --git a/llvm/test/MC/X86/check-end-of-data-region.s b/llvm/test/MC/X86/check-end-of-data-region.s index 50f5dab73d352..f0cf67bf7ed32 100644 --- a/llvm/test/MC/X86/check-end-of-data-region.s +++ b/llvm/test/MC/X86/check-end-of-data-region.s @@ -5,4 +5,4 @@ foo: .long 0 -// CHECK-ERROR: LLVM ERROR: Data region not terminated +// CHECK-ERROR: LLVM ERROR: data region not terminated From 5b27878e5c6b9055436b917868266b7fd05414bb Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Jul 2026 09:51:15 +0200 Subject: [PATCH 083/125] COFF: Start error message with lowercase letter (#208636) Follow style guideline for error messages. --- llvm/lib/Object/COFFObjectFile.cpp | 2 +- llvm/test/Object/coff-invalid.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 0231206ea1e79..08458f8345209 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -396,7 +396,7 @@ relocation_iterator COFFObjectFile::section_rel_begin(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); const coff_relocation *begin = getFirstReloc(Sec, Data, base()); if (begin && Sec->VirtualAddress != 0) - report_fatal_error("Sections with relocations should have an address of 0"); + report_fatal_error("sections with relocations should have an address of 0"); DataRefImpl Ret; Ret.p = reinterpret_cast(begin); return relocation_iterator(RelocationRef(Ret, this)); diff --git a/llvm/test/Object/coff-invalid.test b/llvm/test/Object/coff-invalid.test index da5d687c6e208..d7b0f348b3028 100644 --- a/llvm/test/Object/coff-invalid.test +++ b/llvm/test/Object/coff-invalid.test @@ -10,4 +10,4 @@ SECTIONS-NEXT: VirtualAddress: 0x1000000 RUN: not --crash llvm-readobj -r %p/Inputs/invalid-bad-section-address.coff 2>&1 | \ RUN: FileCheck %s -CHECK: Sections with relocations should have an address of 0 +CHECK: sections with relocations should have an address of 0 From 2d5aa733913c0691e8c8f2b9a43dc4cb82279f8d Mon Sep 17 00:00:00 2001 From: Zeyi Xu Date: Fri, 10 Jul 2026 15:52:15 +0800 Subject: [PATCH 084/125] [clang-tidy] Add IgnoreMacros option to readability-trivial-switch (#208622) AI Usage: Assisted by Codex 5.6 Closes https://github.com/llvm/llvm-project/issues/208474 --- .../clang-tidy/readability/TrivialSwitchCheck.cpp | 12 ++++++++++++ .../clang-tidy/readability/TrivialSwitchCheck.h | 7 +++++-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++ .../checks/readability/trivial-switch.rst | 8 ++++++++ .../checkers/readability/trivial-switch.cpp | 14 ++++++++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp index 5b5fe4c48724b..d77163009358b 100644 --- a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.cpp @@ -12,12 +12,24 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { +TrivialSwitchCheck::TrivialSwitchCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} + +void TrivialSwitchCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void TrivialSwitchCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(switchStmt().bind("switch"), this); } void TrivialSwitchCheck::check(const MatchFinder::MatchResult &Result) { const auto *Switch = Result.Nodes.getNodeAs("switch"); + if (IgnoreMacros && Switch->getBeginLoc().isMacroID()) + return; + std::size_t CaseCount = 0; bool HasDefault = false; diff --git a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h index 9eff86475932d..28afb74500332 100644 --- a/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h +++ b/clang-tools-extra/clang-tidy/readability/TrivialSwitchCheck.h @@ -19,13 +19,16 @@ namespace clang::tidy::readability { /// https://clang.llvm.org/extra/clang-tidy/checks/readability/trivial-switch.html class TrivialSwitchCheck : public ClangTidyCheck { public: - TrivialSwitchCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + TrivialSwitchCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; std::optional getCheckTraversalKind() const override { return TK_IgnoreUnlessSpelledInSource; } + +private: + const bool IgnoreMacros; }; } // namespace clang::tidy::readability diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 082cc5cb78bc0..5abcc053652ee 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -910,6 +910,11 @@ Changes in existing checks ` check by avoiding a crash from invalid ``Abbreviations`` option. +- Improved :doc:`readability-trivial-switch + ` check by adding an + `IgnoreMacros` option. When enabled, the check will ignore switch + statements originating from macros. + - Improved :doc:`readability-use-anyofallof ` check by emitting a diagnostic note to suggest materializing the temporary range when iterating over temporary diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst index efcee2f0c7caf..dfed2576ffa81 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/trivial-switch.rst @@ -34,3 +34,11 @@ Otherwise, the ``switch`` can be better expressed with an ``if`` statement. // The switch without any labels will be diagnosed. int i = 42; switch (i) {} + +Options +------- + +.. option:: IgnoreMacros + + If set to `true`, the check will not give warnings inside macros. Default + is `true`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp index bc693df6599c4..b01f0d8462f3b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/trivial-switch.cpp @@ -1,4 +1,7 @@ // RUN: %check_clang_tidy -std=c++98-or-later %s readability-trivial-switch %t +// RUN: %check_clang_tidy -std=c++98-or-later -check-suffixes=,MACROS %s \ +// RUN: readability-trivial-switch %t -- \ +// RUN: -config="{CheckOptions: {readability-trivial-switch.IgnoreMacros: false}}" void bad(int I) { switch (I) { @@ -42,3 +45,14 @@ void good(int I) { break; } } + +#define SINGLE_CASE_SWITCH(I) \ + switch (I) { \ + case 0: \ + break; \ + } + +void macro(int I) { + SINGLE_CASE_SWITCH(I) + // CHECK-MESSAGES-MACROS: :[[@LINE-1]]:3: warning: switch with only one case; use an if statement +} From 03aca1aebe3dff60130f0383ec842ddd3f756405 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 10 Jul 2026 09:53:15 +0200 Subject: [PATCH 085/125] [AMDGPU] Introduce tests for PR207922 (NFC) (#208640) --- .../CodeGen/AMDGPU/rewrite-out-arguments-2.ll | 349 ++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll diff --git a/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll new file mode 100644 index 0000000000000..5a35d603e9703 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/rewrite-out-arguments-2.ll @@ -0,0 +1,349 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-rewrite-out-arguments < %s | FileCheck %s + +define i32 @load_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @load_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load i32, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @load_out_ptr_before_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @load_out_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[LOAD:%.*]] = load i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + %load = load i32, ptr addrspace(5) %out + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @volatile_load_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @volatile_load_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load volatile i32, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @atomic_load_out_ptr_before_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define i32 @atomic_load_out_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[OUT]] monotonic, align 4 +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + %load = load atomic i32, ptr addrspace(5) %out monotonic, align 4 + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define void @volatile_store_out_ptr(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @volatile_store_out_ptr( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store volatile i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: ret void +; + store volatile i32 0, ptr addrspace(5) %out + ret void +} + +define void @atomic_store_out_ptr(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @atomic_store_out_ptr( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store atomic i32 0, ptr addrspace(5) [[OUT]] monotonic, align 4 +; CHECK-NEXT: ret void +; + store atomic i32 0, ptr addrspace(5) %out monotonic, align 4 + ret void +} + +define void @atomic_store_out_ptr_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @atomic_store_out_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[OUT]] release, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %out release, align 4 + ret void +} + +define i32 @load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @load_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_AFTER_STORE:%.*]] @[[LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load i32, ptr addrspace(5) %ptr + ret i32 %load +} + +define i32 @volatile_load_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @volatile_load_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_AFTER_STORE:%.*]] @[[VOLATILE_LOAD_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load volatile i32, ptr addrspace(5) %ptr + ret i32 %load +} + +define i32 @atomic_load_acquire_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @atomic_load_acquire_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: [[LOAD:%.*]] = load atomic i32, ptr addrspace(5) [[PTR]] acquire, align 4 +; CHECK-NEXT: ret i32 [[LOAD]] +; + store i32 0, ptr addrspace(5) %out + %load = load atomic i32, ptr addrspace(5) %ptr acquire, align 4 + ret i32 %load +} + +define i32 @atomic_load_monotonic_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @atomic_load_monotonic_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE:%.*]] @[[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[ATOMIC_LOAD_MONOTONIC_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + store i32 0, ptr addrspace(5) %out + %load = load atomic i32, ptr addrspace(5) %ptr monotonic, align 4 + ret i32 %load +} + +define void @volatile_store_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @volatile_store_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store volatile i32 1, ptr addrspace(5) [[PTR]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store volatile i32 1, ptr addrspace(5) %ptr + ret void +} + +define void @atomic_store_release_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_release_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] release, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr release, align 4 + ret void +} + +define void @atomic_store_unordered_ptr_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_unordered_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: store atomic i32 1, ptr addrspace(5) [[PTR]] unordered, align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr unordered, align 4 + ret void +} + +define void @opaque_read_call_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @opaque_read_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP2:%.*]] = call [[OPAQUE_READ_CALL_AFTER_STORE:%.*]] @[[OPAQUE_READ_CALL_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison) +; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[OPAQUE_READ_CALL_AFTER_STORE]] [[TMP2]], 0 +; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque_read() + ret void +} + +define void @opaque_rw_call_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @opaque_rw_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @opaque_rw_argmem(ptr addrspace(5) [[PTR]]) +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque_rw_argmem(ptr addrspace(5) %ptr) + ret void +} + +define void @opaque_call_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @opaque_call_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @opaque() +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @opaque() + ret void +} + +define void @memcpy_after_store(ptr addrspace(5) %out, ptr addrspace(5) %src, ptr addrspace(5) noalias %dst) { +; CHECK-LABEL: define void @memcpy_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]], ptr addrspace(5) noalias [[TMP2:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP4:%.*]] = call [[MEMCPY_AFTER_STORE:%.*]] @[[MEMCPY_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]], ptr addrspace(5) [[TMP2]]) +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[MEMCPY_AFTER_STORE]] [[TMP4]], 0 +; CHECK-NEXT: store i32 [[TMP5]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memcpy.p5.p5.i32(ptr addrspace(5) %dst, ptr addrspace(5) %src, i32 4, i1 false) + ret void +} + +define void @memset_after_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @memset_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]], ptr addrspace(5) [[PTR:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: call void @llvm.memset.p5.i32(ptr addrspace(5) [[PTR]], i8 0, i32 4, i1 false) +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false) + ret void +} + +define void @memset_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) { +; CHECK-LABEL: define void @memset_noalias_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[MEMSET_NOALIAS_PTR_AFTER_STORE:%.*]] @[[MEMSET_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[MEMSET_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + call void @llvm.memset.p5.i32(ptr addrspace(5) %ptr, i8 0, i32 4, i1 false) + ret void +} + +define i32 @load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @load_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[LOAD_PTR_BEFORE_STORE:%.*]] @[[LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + %load = load i32, ptr addrspace(5) %ptr + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define i32 @volatile_load_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define i32 @volatile_load_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[VOLATILE_LOAD_PTR_BEFORE_STORE:%.*]] @[[VOLATILE_LOAD_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = extractvalue [[VOLATILE_LOAD_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: ret i32 [[TMP5]] +; + %load = load volatile i32, ptr addrspace(5) %ptr + store i32 0, ptr addrspace(5) %out + ret i32 %load +} + +define void @atomic_store_release_ptr_before_store(ptr addrspace(5) %out, ptr addrspace(5) %ptr) { +; CHECK-LABEL: define void @atomic_store_release_ptr_before_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]], ptr addrspace(5) [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE:%.*]] @[[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_RELEASE_PTR_BEFORE_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store atomic i32 1, ptr addrspace(5) %ptr release, align 4 + store i32 0, ptr addrspace(5) %out + ret void +} + +define void @atomic_store_seq_cst_noalias_ptr_after_store(ptr addrspace(5) noalias %out, ptr addrspace(5) noalias %ptr) { +; CHECK-LABEL: define void @atomic_store_seq_cst_noalias_ptr_after_store( +; CHECK-SAME: ptr addrspace(5) noalias [[TMP0:%.*]], ptr addrspace(5) noalias [[TMP1:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP3:%.*]] = call [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE:%.*]] @[[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison, ptr addrspace(5) [[TMP1]]) +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue [[ATOMIC_STORE_SEQ_CST_NOALIAS_PTR_AFTER_STORE]] [[TMP3]], 0 +; CHECK-NEXT: store i32 [[TMP4]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + store atomic i32 1, ptr addrspace(5) %ptr seq_cst, align 4 + ret void +} + +define void @fence_release_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @fence_release_after_store( +; CHECK-SAME: ptr addrspace(5) [[TMP0:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP2:%.*]] = call [[FENCE_RELEASE_AFTER_STORE:%.*]] @[[FENCE_RELEASE_AFTER_STORE_BODY:[a-zA-Z0-9_$\"\\.-]*[a-zA-Z_$\"\\.-][a-zA-Z0-9_$\"\\.-]*]](ptr addrspace(5) poison) +; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [[FENCE_RELEASE_AFTER_STORE]] [[TMP2]], 0 +; CHECK-NEXT: store i32 [[TMP3]], ptr addrspace(5) [[TMP0]], align 4 +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + fence release + ret void +} + +define void @fence_seq_cst_after_store(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @fence_seq_cst_after_store( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: fence seq_cst +; CHECK-NEXT: ret void +; + store i32 0, ptr addrspace(5) %out + fence seq_cst + ret void +} + +define void @store_cross_bb(ptr addrspace(5) %out) { +; CHECK-LABEL: define void @store_cross_bb( +; CHECK-SAME: ptr addrspace(5) [[OUT:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: store i32 0, ptr addrspace(5) [[OUT]], align 4 +; CHECK-NEXT: br label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + store i32 0, ptr addrspace(5) %out + br label %exit + +exit: + ret void +} + +declare void @opaque_read() memory(read) +declare void @opaque() +declare void @opaque_rw_argmem(ptr addrspace(5)) memory(argmem: readwrite) +declare void @llvm.memcpy.p5.p5.i32(ptr addrspace(5), ptr addrspace(5), i32, i1) +declare void @llvm.memset.p5.i32(ptr addrspace(5), i8, i32, i1) From 977f4d603ae13c751357352f1256e389a4725e9f Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Fri, 10 Jul 2026 09:55:33 +0200 Subject: [PATCH 086/125] [AMDGPU] Employ MemorySSA when rewriting out arguments (NFCI) (#207922) While transitioning away from MemoryDependenceAnalysis, replace MDA `getPointerDependencyFrom` query with a reverse traversal of the memory accesses of the return basic block (MemoryDefs and MemoryUses), looking for the must-aliasing store to the out argument. The existing behaviour is meant to be preserved. --- .../AMDGPU/AMDGPURewriteOutArguments.cpp | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp index c0802de2763dc..7db637eaa0745 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp @@ -44,7 +44,8 @@ #include "AMDGPU.h" #include "Utils/AMDGPUBaseInfo.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/MemorySSA.h" +#include "llvm/Analysis/MemorySSAUpdater.h" #include "llvm/IR/AttributeMask.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" @@ -81,7 +82,9 @@ namespace { class AMDGPURewriteOutArguments : public FunctionPass { private: const DataLayout *DL = nullptr; - MemoryDependenceResults *MDA = nullptr; + MemorySSA *MSSA = nullptr; + MemorySSAUpdater *MSSAU = nullptr; + AAResults *AA = nullptr; Type *getStoredType(Value &Arg) const; Type *getOutArgumentType(Argument &Arg) const; @@ -92,7 +95,8 @@ class AMDGPURewriteOutArguments : public FunctionPass { AMDGPURewriteOutArguments() : FunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); + AU.addRequired(); FunctionPass::getAnalysisUsage(AU); } @@ -104,7 +108,7 @@ class AMDGPURewriteOutArguments : public FunctionPass { INITIALIZE_PASS_BEGIN(AMDGPURewriteOutArguments, DEBUG_TYPE, "AMDGPU Rewrite Out Arguments", false, false) -INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass) +INITIALIZE_PASS_DEPENDENCY(MemorySSAWrapperPass) INITIALIZE_PASS_END(AMDGPURewriteOutArguments, DEBUG_TYPE, "AMDGPU Rewrite Out Arguments", false, false) @@ -170,6 +174,49 @@ bool AMDGPURewriteOutArguments::doInitialization(Module &M) { return false; } +static StoreInst *findStoreForOutArgument(BasicBlock *BB, Argument *OutArg, + MemorySSA &MSSA, + BatchAAResults &BAA) { + MemoryLocation ArgLoc = MemoryLocation::getBeforeOrAfter(OutArg); + const auto *Accesses = MSSA.getBlockAccesses(BB); + if (!Accesses) + return nullptr; + + for (const MemoryAccess &Access : reverse(*Accesses)) { + const auto *UseOrDef = dyn_cast(&Access); + if (!UseOrDef) + continue; + + Instruction *I = UseOrDef->getMemoryInst(); + + // Return the must-alias store to the out argument. + if (auto *Store = dyn_cast(I)) + if (Store->getPointerOperand() == OutArg) + return Store; + + if (auto *FI = dyn_cast(I)) + if (FI->getOrdering() == AtomicOrdering::Release) + continue; + + if (auto *LI = dyn_cast(I)) { + if (LI->isAtomic()) { + // May-alias reads with monotonic ordering are ignored. + if (isStrongerThan(LI->getOrdering(), AtomicOrdering::Monotonic)) + return nullptr; + continue; + } + } + + // Any other memory access that writes the location prevents the + // rewrite. + // FIXME: should handle aliasing reads too. + if (isModSet(BAA.getModRefInfo(I, ArgLoc))) + return nullptr; + } + + return nullptr; +} + bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { if (skipFunction(F)) return false; @@ -179,8 +226,6 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { AMDGPU::isEntryFunctionCC(F.getCallingConv())) return false; - MDA = &getAnalysis().getMemDep(); - unsigned ReturnNumRegs = 0; // Maps an out-argument number to its field index in the return struct. // Fields are in processing order, which the retry loop below can reorder @@ -222,6 +267,13 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { if (Returns.empty()) return false; + AA = &getAnalysis().getAAResults(); + MSSA = &getAnalysis().getMSSA(); + + BatchAAResults BatchAA(*AA); + MemorySSAUpdater MSSAUpdater(MSSA); + MSSAU = &MSSAUpdater; + bool Changing; do { @@ -254,17 +306,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { for (ReturnInst *RI : Returns) { BasicBlock *BB = RI->getParent(); - MemDepResult Q = MDA->getPointerDependencyFrom( - MemoryLocation::getBeforeOrAfter(OutArg), true, BB->end(), BB, RI); - StoreInst *SI = nullptr; - if (Q.isDef()) - SI = dyn_cast(Q.getInst()); - - // MDA stops at the first may-aliasing store, which need not be to this - // argument; only fold a store whose pointer is exactly OutArg. - if (SI && SI->getPointerOperand() != OutArg) - SI = nullptr; - + StoreInst *SI = findStoreForOutArgument(BB, OutArg, *MSSA, BatchAA); if (SI) { LLVM_DEBUG(dbgs() << "Found out argument store: " << *SI << '\n'); ReplaceableStores.emplace_back(RI, SI); @@ -291,6 +333,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { } ValVec.emplace_back(OutArg, ReplVal); + MSSAU->removeMemoryAccess(Store.second); Store.second->eraseFromParent(); } From 4516eb3a1fbdf2897db5cbe677de7458e06a1776 Mon Sep 17 00:00:00 2001 From: Tim Corringham Date: Fri, 10 Jul 2026 09:08:44 +0100 Subject: [PATCH 087/125] [HLSL] Implement RWTexture2D (#208267) Add HLSL front-end support for RWTexture2D and related test cases. Where appropriate test cases have been parameterized across the Texture2D types (and redundant Texture2DArray tests removed). Assisted by Cursor Fixes: #194742 --------- Co-authored-by: Tim Corringham --- clang/lib/Sema/HLSLExternalSemaSource.cpp | 35 +++ clang/test/AST/HLSL/Texture2D-AST.hlsl | 178 +++++++++++++++ .../resources/Texture2D-GetDimensions.hlsl | 83 ++++--- .../CodeGenHLSL/resources/Texture2D-Load.hlsl | 215 +++++++++--------- .../Texture2DArray-GetDimensions.hlsl | 103 --------- .../Resources/RWTexture2D-mips-errors.hlsl | 19 ++ ...WTexture2D-unsupported-methods-errors.hlsl | 37 +++ .../Resources/Texture2D-GetDimensions.hlsl | 6 +- .../Texture2D-Load-errors.hlsl | 35 ++- .../SemaHLSL/Texture2DArray-Load-errors.hlsl | 44 ---- 10 files changed, 456 insertions(+), 299 deletions(-) create mode 100644 clang/test/AST/HLSL/Texture2D-AST.hlsl delete mode 100644 clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl create mode 100644 clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl create mode 100644 clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl rename clang/test/SemaHLSL/{ => Resources}/Texture2D-Load-errors.hlsl (52%) delete mode 100644 clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index 1d2a3983a639d..115795ca74bae 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -281,6 +281,22 @@ static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S, .addGatherCmpMethods(Dim, IsArray); } +/// Set up RWTexture type: UAV texture with only operator[] (uint2, read/write), +/// Load and GetDimensions (no sample/gather/mips/LOD). +static BuiltinTypeDeclBuilder setupRWTextureType(CXXRecordDecl *Decl, Sema &S, + bool IsArray, + ResourceDimension Dim) { + return BuiltinTypeDeclBuilder(S, Decl) + .addTextureHandle(ResourceClass::UAV, /*IsROV=*/false, IsArray, Dim) + .addTextureLoadMethods(Dim, IsArray) + .addArraySubscriptOperators(Dim, IsArray) + .addGetDimensionsMethods(Dim) + .addDefaultHandleConstructor() + .addCopyConstructor() + .addCopyAssignmentOperator() + .addStaticInitializationFunctions(false); +} + // Add a partial specialization for a template. The `TextureTemplate` is // `Texture`, and it will be specialized for vectors: // `Texture>`. @@ -691,6 +707,25 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { .completeDefinition(); }); + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWTexture2D") + .addSimpleTemplateParams({"element_type"}, {Float4Ty}, + TypedBufferConcept) + .finalizeForwardDeclaration(); + + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false, + ResourceDimension::Dim2D) + .completeDefinition(); + }); + + auto *PartialSpecRW = addVectorTexturePartialSpecialization( + *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate()); + onCompletion(PartialSpecRW, [this](CXXRecordDecl *Decl) { + setupRWTextureType(Decl, *SemaPtr, /*IsArray=*/false, + ResourceDimension::Dim2D) + .completeDefinition(); + }); + // Texture2DArray — same as Texture2D but IsArray=true Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "Texture2DArray") .addSimpleTemplateParams({"element_type"}, {Float4Ty}, diff --git a/clang/test/AST/HLSL/Texture2D-AST.hlsl b/clang/test/AST/HLSL/Texture2D-AST.hlsl new file mode 100644 index 0000000000000..23d0b8138b39b --- /dev/null +++ b/clang/test/AST/HLSL/Texture2D-AST.hlsl @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | FileCheck %s --check-prefixes=CHECK,SRV -DTEXTURE=Texture2D -DSZ=2 -DKIND=SRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | FileCheck %s --check-prefixes=CHECK,SRV,SRV-ARR -DTEXTURE=Texture2DArray -DSZ=3 -DKIND=SRV +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DRW=1 -o - %s | FileCheck %s --check-prefixes=CHECK,UAV,UAV-STORE,UAV-TRUNC -DTEXTURE=RWTexture2D -DSZ=2 -DKIND=UAV + +// CHECK: ClassTemplateDecl {{.*}} [[TEXTURE]] +// CHECK: TemplateTypeParmDecl {{.*}} element_type +// CHECK: CXXRecordDecl {{.*}} [[TEXTURE]] definition +// CHECK: FinalAttr {{.*}} Implicit final +// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] + +// SRV: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(vector) const' inline +// SRV-NEXT: ParmVarDecl {{.*}} Index 'vector' +// SRV-NEXT: CompoundStmt +// SRV-NEXT: ReturnStmt +// SRV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow +// SRV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' +// SRV-NEXT: CallExpr {{.*}} '' +// SRV-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// SRV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// SRV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// SRV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// SRV-SAME: ' lvalue .__handle +// SRV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue implicit this +// SRV-NEXT: DeclRefExpr {{.*}} 'vector' lvalue ParmVar {{.*}} 'Index' 'vector' +// SRV-NEXT: AlwaysInlineAttr + +// UAV: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(vector) const' inline +// UAV-NEXT: ParmVarDecl {{.*}} Index 'vector' +// UAV-NEXT: CompoundStmt +// UAV-NEXT: ReturnStmt +// UAV-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' lvalue prefix '*' cannot overflow +// UAV-NEXT: CStyleCastExpr {{.*}} 'hlsl_device element_type *' +// UAV-NEXT: CallExpr {{.*}} '' +// UAV-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// UAV-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// UAV-SAME: ' lvalue .__handle +// UAV-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue implicit this +// UAV-NEXT: DeclRefExpr {{.*}} 'vector' lvalue ParmVar {{.*}} 'Index' 'vector' +// UAV-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)' +// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)' +// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: CallExpr {{.*}} '' +// CHECK-NEXT: DeclRefExpr {{.*}} '' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept' +// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t +// SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// SRV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// UAV-ARR-SAME{LITERAL}: [[hlsl::is_array]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]] +// CHECK-SAME: ' lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[TEXTURE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict' +// CHECK-NEXT: AlwaysInlineAttr + +// CHECK: ClassTemplatePartialSpecializationDecl {{.*}} class [[TEXTURE]] explicit_specialization +// CHECK: TemplateTypeParmDecl {{.*}} element_type +// CHECK: NonTypeTemplateParmDecl {{.*}} element_count + +// SRV-NOT: BinaryOperator {{.*}} 'hlsl_device float' lvalue '=' + +// UAV-STORE-LABEL: FunctionDecl {{.*}} main 'void ()' +// UAV-STORE: BinaryOperator {{.*}} 'hlsl_device float' lvalue '=' +// UAV-STORE-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl_device float' lvalue '[]' +// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float &(*)(vector) const' +// UAV-STORE-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(vector) const' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float &(vector) const' +// UAV-STORE-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[TEXTURE]]' lvalue +// UAV-STORE-NEXT: DeclRefExpr {{.*}} '[[TEXTURE]]':'hlsl::[[TEXTURE]]' lvalue Var {{.*}} 't' '[[TEXTURE]]':'hlsl::[[TEXTURE]]' +// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'vector' +// UAV-TRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector' +// UAV-TRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector' lvalue Var {{.*}} 'i' 'uint3':'vector' +// UAV-NOTRUNC-NEXT: ImplicitCastExpr {{.*}} 'uint3':'vector' +// UAV-NOTRUNC-NEXT: DeclRefExpr {{.*}} 'uint3':'vector' lvalue Var {{.*}} 'i' 'uint3':'vector' +// UAV-STORE-NEXT: FloatingLiteral {{.*}} 'float' {{.*}} + +TEXTURE t; + +void main() { + uint3 i = uint3(0, 0, 0); +#if RW + t[i] = 1.0f; +#endif + float x = t[i]; + (void)x; + uint w, h; + t.GetDimensions(w, h); +} diff --git a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl index 87b6506c663b0..25f123a47649b 100644 --- a/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl +++ b/clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl @@ -1,24 +1,33 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV +// Texture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D -DDXILTY=2 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D -DARRAYED=0 -DSAMPLED=1 -DFORMAT=0 -Texture2D Tex : register(t0); +// Texture2DArray +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray -DDXILTY=7 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray -DARRAYED=1 -DSAMPLED=1 -DFORMAT=0 -// CHECK: define {{.*}} void @test_uint_dims() -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) +// RWTexture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D -DDXILTY=2 -DRW=1 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D -DARRAYED=0 -DSAMPLED=2 -DFORMAT=1 + +// When RWTexture2DArray is implemented, add DXIL/SPIRV runs with DXILTY=7, RW=1, ARRAYED=1, SAMPLED=2, FORMAT=1. + +TEXTURE Tex; + +// CHECK: define {{.*}} void @test_uint_dims{{(\(\))?}}() +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) void test_uint_dims() { uint w, h; Tex.GetDimensions(w, h); } -// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded. - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]]) +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]]) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 // CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] @@ -26,21 +35,21 @@ void test_uint_dims() { // CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 // CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] -// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %{{.*}}) +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) void test_uint_levels_dims(uint mipLevel) { uint w, h, l; Tex.GetDimensions(mipLevel, w, h, l); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] // CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]]) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]], i32 %[[MIP_VAL]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 // CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] @@ -51,20 +60,20 @@ void test_uint_levels_dims(uint mipLevel) { // CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 // CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]] -// CHECK: define {{.*}} void @test_float_dims() -// CHECK: call void @hlsl::Texture2D::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_float_dims{{(\(\))?}}() +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) void test_float_dims() { float w, h; Tex.GetDimensions(w, h); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]]) +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]]) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 // CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float @@ -74,21 +83,21 @@ void test_float_dims() { // CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float // CHECK: store float %[[H_F]], ptr %[[H_PTR]] -// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2D::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) +// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %{{.*}}) +// CHECK: call void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) void test_float_levels_dims(uint mipLevel) { float w, h, l; Tex.GetDimensions(mipLevel, w, h, l); } -// CHECK: define linkonce_odr hidden void @hlsl::Texture2D::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) +// CHECK: define linkonce_odr hidden void @hlsl::[[TEXTURE]]::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]] +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 +// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]), ptr %[[HANDLE_GEP]] +// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]), ptr %[[HANDLE_GEP]] // CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], i32 %[[MIP_VAL]]) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT]]) %[[HANDLE]], i32 %[[MIP_VAL]]) // CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] // CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 // CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float diff --git a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl index 7c30a211149e7..d69a0f6ddaa89 100644 --- a/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl +++ b/clang/test/CodeGenHLSL/resources/Texture2D-Load.hlsl @@ -1,238 +1,247 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV +// Texture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DDXILTY=2 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DARRAYED=0 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DRW=0 -Texture2D t; +// Texture2DArray +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 -DARG3=", i32 2" -DDXILTY=7 -DRW=0 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=Texture2DArray -DLOCTY=int4 -DZEROS=" 0, 0" -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=Texture2DArray -DLOCSZ=4 -DCOORDSZ=3 -DARG3=", i32 2" -DARRAYED=1 -DSAMPLED=1 -DFORMAT1=0 -DFORMAT3=0 -DFORMAT6=0 -DFORMAT21=0 -DFORMAT24=0 -DFORMAT25=0 -DRW=0 + +// RWTexture2D +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DDXILTY=2 -DRW=1 +// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -DTEXTURE=RWTexture2D -DLOCTY=int3 -DZEROS=0 -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV -DTEXTURE=RWTexture2D -DLOCSZ=3 -DCOORDSZ=2 -DARG3= -DARRAYED=0 -DSAMPLED=2 -DFORMAT1=1 -DFORMAT3=3 -DFORMAT6=6 -DFORMAT21=21 -DFORMAT24=24 -DFORMAT25=25 + +TEXTURE t; // CHECK: define hidden {{.*}} <4 x float> @test_load(int vector[2]) -// CHECK: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2 -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t, <3 x i32> noundef %[[COORD]]) +// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 [[COORDSZ]] +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t, <[[LOCSZ]] x i32> noundef %[[COORD]]) // CHECK: ret <4 x float> %[[CALL]] float4 test_load(int2 loc : LOC) : SV_Target { - return t.Load(int3(loc, 0)); + return t.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) +// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) // CHECK: %[[THIS_ADDR:.*]] = alloca ptr -// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32> +// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32> // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]] -// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] +// CHECK: store <[[LOCSZ]] x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]] -// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]] -// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> poison, <2 x i32> -// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2 -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]] +// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], <[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> +// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], i64 [[COORDSZ]] +// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}(target("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}(target("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> zeroinitializer) // CHECK: ret <4 x float> %[[RES]] // CHECK: define hidden {{.*}} <4 x float> @test_load_offset(int vector[2]) -// CHECK: %[[COORD:.*]] = insertelement <3 x i32> {{.*}}, i32 0, i32 2 -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t, <3 x i32> noundef %[[COORD]], <2 x i32> noundef splat (i32 1)) +// CHECK: %[[COORD:.*]] = insertelement <[[LOCSZ]] x i32> {{.*}}, i32 0, i32 [[COORDSZ]] +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t, <[[LOCSZ]] x i32> noundef %[[COORD]], <2 x i32> noundef splat (i32 1)) // CHECK: ret <4 x float> %[[CALL]] float4 test_load_offset(int2 loc : LOC) : SV_Target { - return t.Load(int3(loc, 0), int2(1, 1)); + return t.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// CHECK: define linkonce_odr hidden {{.*}} <4 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) // CHECK: %[[THIS_ADDR:.*]] = alloca ptr -// CHECK: %[[LOCATION_ADDR:.*]] = alloca <3 x i32> +// CHECK: %[[LOCATION_ADDR:.*]] = alloca <[[LOCSZ]] x i32> // CHECK: %[[OFFSET_ADDR:.*]] = alloca <2 x i32> // CHECK: store ptr %[[THIS]], ptr %[[THIS_ADDR]] -// CHECK: store <3 x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] +// CHECK: store <[[LOCSZ]] x i32> %[[LOCATION]], ptr %[[LOCATION_ADDR]] // CHECK: store <2 x i32> %[[OFFSET]], ptr %[[OFFSET_ADDR]] // CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS_ADDR]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0 +// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::[[TEXTURE]]", ptr %[[THIS_VAL]], i32 0, i32 0 // CHECK: %[[HANDLE:.*]] = load target("{{(dx.Texture|spirv.Image)}}", {{.*}}), ptr %[[HANDLE_GEP]] -// CHECK: %[[LOCATION_VAL:.*]] = load <3 x i32>, ptr %[[LOCATION_ADDR]] -// CHECK: %[[COORD:.*]] = shufflevector <3 x i32> %[[LOCATION_VAL]], <3 x i32> poison, <2 x i32> -// CHECK: %[[LOD:.*]] = extractelement <3 x i32> %[[LOCATION_VAL]], i64 2 +// CHECK: %[[LOCATION_VAL:.*]] = load <[[LOCSZ]] x i32>, ptr %[[LOCATION_ADDR]] +// CHECK: %[[COORD:.*]] = shufflevector <[[LOCSZ]] x i32> %[[LOCATION_VAL]], <[[LOCSZ]] x i32> poison, <[[COORDSZ]] x i32> +// CHECK: %[[LOD:.*]] = extractelement <[[LOCSZ]] x i32> %[[LOCATION_VAL]], i64 [[COORDSZ]] // CHECK: %[[OFFSET_VAL:.*]] = load <2 x i32>, ptr %[[OFFSET_ADDR]] -// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) -// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], <2 x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// DXIL: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.dx.resource.load.level.v4f32.tdx.Texture_v4f32_{{.*}}("dx.Texture", <4 x float>, [[RW]], 0, 0, [[DXILTY]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) +// SPIRV: %[[RES:.*]] = call {{.*}} <4 x float> @llvm.spv.resource.load.level.v4f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT1]]) %[[HANDLE]], <[[COORDSZ]] x i32> %[[COORD]], i32 %[[LOD]], <2 x i32> %[[OFFSET_VAL]]) // CHECK: ret <4 x float> %[[RES]] // For the rest of the types, we just check that the call to the member // function has the correct return type. -Texture2D t_float; +TEXTURE t_float; // CHECK: define hidden {{.*}} float @test_load_float(int vector[2]) -// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret float %[[RES]] float test_load_float(int2 loc : LOC) { - return t_float.Load(int3(loc, 0)); + return t_float.Load(LOCTY(loc, ZEROS)); } // CHECK: define hidden {{.*}} float @test_load_offset_float(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret float %[[CALL]] float test_load_offset_float(int2 loc : LOC) { - return t_float.Load(int3(loc, 0), int2(1, 1)); + return t_float.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", float, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} float @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} float @llvm.dx.resource.load.level.f32.tdx.Texture_f32_{{.*}}("dx.Texture", float, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} float @llvm.spv.resource.load.level.f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT3]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret float %[[RES]] -Texture2D t_float2; +TEXTURE t_float2; // CHECK: define hidden {{.*}} <2 x float> @test_load_float2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_float2, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float2, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <2 x float> %[[CALL]] float2 test_load_float2(int2 loc : LOC) { - return t_float2.Load(int3(loc, 0)); + return t_float2.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <2 x float> %[[RES]] // CHECK: define hidden {{.*}} <2 x float> @test_load_offset_float2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float2, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float2, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <2 x float> %[[CALL]] float2 test_load_offset_float2(int2 loc : LOC) { - return t_float2.Load(int3(loc, 0), int2(1, 1)); + return t_float2.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <2 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.dx.resource.load.level.v2f32.tdx.Texture_v2f32_{{.*}}("dx.Texture", <2 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} <2 x float> @llvm.spv.resource.load.level.v2f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT6]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <2 x float> %[[RES]] -Texture2D t_float3; +TEXTURE t_float3; // CHECK: define hidden {{.*}} <3 x float> @test_load_float3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_float3, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_float3, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <3 x float> %[[CALL]] float3 test_load_float3(int2 loc : LOC) { - return t_float3.Load(int3(loc, 0)); + return t_float3.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <3 x float> %[[RES]] // CHECK: define hidden {{.*}} <3 x float> @test_load_offset_float3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_float3, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_float3, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <3 x float> %[[CALL]] float3 test_load_offset_float3(int2 loc : LOC) { - return t_float3.Load(int3(loc, 0), int2(1, 1)); + return t_float3.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_0_0_0_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x float>, 0, 0, 0, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <3 x float> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.dx.resource.load.level.v3f32.tdx.Texture_v3f32_{{.*}}("dx.Texture", <3 x float>, [[RW]], 0, 0, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call {{.*}} <3 x float> @llvm.spv.resource.load.level.v3f32.tspirv.Image_f32_{{.*}}("spirv.Image", float, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <3 x float> %[[RES]] -Texture2D t_int; +TEXTURE t_int; // CHECK: define hidden {{.*}} i32 @test_load_int(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret i32 %[[CALL]] int test_load_int(int2 loc : LOC) { - return t_int.Load(int3(loc, 0)); + return t_int.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret i32 %[[RES]] // CHECK: define hidden {{.*}} i32 @test_load_offset_int(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret i32 %[[CALL]] int test_load_offset_int(int2 loc : LOC) { - return t_int.Load(int3(loc, 0), int2(1, 1)); + return t_int.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", i32, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} i32 @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call i32 @llvm.dx.resource.load.level.i32.tdx.Texture_i32_{{.*}}("dx.Texture", i32, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call i32 @llvm.spv.resource.load.level.i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT24]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret i32 %[[RES]] -Texture2D t_int2; +TEXTURE t_int2; // CHECK: define hidden {{.*}} <2 x i32> @test_load_int2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int2, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int2, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <2 x i32> %[[CALL]] int2 test_load_int2(int2 loc : LOC) { - return t_int2.Load(int3(loc, 0)); + return t_int2.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <2 x i32> %[[RES]] // CHECK: define hidden {{.*}} <2 x i32> @test_load_offset_int2(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int2, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int2, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <2 x i32> %[[CALL]] int2 test_load_offset_int2(int2 loc : LOC) { - return t_int2.Load(int3(loc, 0), int2(1, 1)); + return t_int2.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <2 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <2 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.load.level.v2i32.tdx.Texture_v2i32_{{.*}}("dx.Texture", <2 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.load.level.v2i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT25]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <2 x i32> %[[RES]] -Texture2D t_int3; +TEXTURE t_int3; // CHECK: define hidden {{.*}} <3 x i32> @test_load_int3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int3, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int3, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <3 x i32> %[[CALL]] int3 test_load_int3(int2 loc : LOC) { - return t_int3.Load(int3(loc, 0)); + return t_int3.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <3 x i32> %[[RES]] // CHECK: define hidden {{.*}} <3 x i32> @test_load_offset_int3(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int3, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int3, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <3 x i32> %[[CALL]] int3 test_load_offset_int3(int2 loc : LOC) { - return t_int3.Load(int3(loc, 0), int2(1, 1)); + return t_int3.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <3 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <3 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.load.level.v3i32.tdx.Texture_v3i32_{{.*}}("dx.Texture", <3 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.load.level.v3i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], 0) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <3 x i32> %[[RES]] -Texture2D t_int4; +TEXTURE t_int4; // CHECK: define hidden {{.*}} <4 x i32> @test_load_int4(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} @t_int4, <3 x i32> noundef %{{.*}}) +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} @t_int4, <[[LOCSZ]] x i32> noundef %{{.*}}) // CHECK: ret <4 x i32> %[[CALL]] int4 test_load_int4(int2 loc : LOC) { - return t_int4.Load(int3(loc, 0)); + return t_int4.Load(LOCTY(loc, ZEROS)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]]) -// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) -// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]]) +// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) +// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> zeroinitializer) // CHECK: ret <4 x i32> %[[RES]] // CHECK: define hidden {{.*}} <4 x i32> @test_load_offset_int4(int vector[2]) -// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} @t_int4, <3 x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) +// CHECK: %[[CALL:.*]] = call {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} @t_int4, <[[LOCSZ]] x i32> noundef %{{.*}}, <2 x i32> noundef splat (i32 1)) // CHECK: ret <4 x i32> %[[CALL]] int4 test_load_offset_int4(int2 loc : LOC) { - return t_int4.Load(int3(loc, 0), int2(1, 1)); + return t_int4.Load(LOCTY(loc, ZEROS), int2(1, 1)); } -// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::Texture2D::Load(int vector[3], int vector[2])(ptr {{.*}} %[[THIS:.*]], <3 x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) -// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_0_0_1_2t.v2i32.i32.v2i32(target("dx.Texture", <4 x i32>, 0, 0, 1, 2) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) -// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_1_2_0_0_1_0t.v2i32.i32.v2i32(target("spirv.SignedImage", i32, 1, 2, 0, 0, 1, 0) %{{.*}}, <2 x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// CHECK: define linkonce_odr hidden {{.*}} <4 x i32> @hlsl::[[TEXTURE]]::Load(int vector[[[LOCSZ]]], int vector[2])(ptr {{.*}} %[[THIS:.*]], <[[LOCSZ]] x i32> {{.*}} %[[LOCATION:.*]], <2 x i32> {{.*}} %[[OFFSET:.*]]) +// DXIL: %[[RES:.*]] = call <4 x i32> @llvm.dx.resource.load.level.v4i32.tdx.Texture_v4i32_{{.*}}("dx.Texture", <4 x i32>, [[RW]], 0, 1, [[DXILTY]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) +// SPIRV: %[[RES:.*]] = call <4 x i32> @llvm.spv.resource.load.level.v4i32.tspirv.SignedImage_i32_{{.*}}("spirv.SignedImage", i32, 1, 2, [[ARRAYED]], 0, [[SAMPLED]], [[FORMAT21]]) %{{.*}}, <[[COORDSZ]] x i32> %{{.*}}, i32 %{{.*}}, <2 x i32> %{{.*}}) // CHECK: ret <4 x i32> %[[RES]] diff --git a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl b/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl deleted file mode 100644 index f295839be4887..0000000000000 --- a/clang/test/CodeGenHLSL/resources/Texture2DArray-GetDimensions.hlsl +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL -// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV - -Texture2DArray Tex : register(t0); - -// CHECK: define {{.*}} void @test_uint_dims() -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) -void test_uint_dims() { - uint w, h; - Tex.GetDimensions(w, h); -} - -// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded. - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 -// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 -// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] - -// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) -void test_uint_levels_dims(uint mipLevel) { - uint w, h, l; - Tex.GetDimensions(mipLevel, w, h, l); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 -// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1 -// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]] -// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]] -// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 -// CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]] - -// CHECK: define {{.*}} void @test_float_dims() -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}}) -void test_float_dims() { - float w, h; - Tex.GetDimensions(w, h); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]]) -// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0 -// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float -// CHECK: store float %[[W_F]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1 -// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float -// CHECK: store float %[[H_F]], ptr %[[H_PTR]] - -// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]]) -// CHECK: call void @hlsl::Texture2DArray::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}}) -void test_float_levels_dims(uint mipLevel) { - float w, h, l; - Tex.GetDimensions(mipLevel, w, h, l); -} - -// CHECK: define linkonce_odr hidden void @hlsl::Texture2DArray::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]]) -// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]] -// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2DArray", ptr %[[THIS_VAL]], i32 0, i32 0 -// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 7), ptr %[[HANDLE_GEP]] -// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 1, 0, 1, 0), ptr %[[HANDLE_GEP]] -// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]] -// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_7t(target("dx.Texture", <4 x float>, 0, 0, 0, 7) %[[HANDLE]], i32 %[[MIP_VAL]]) -// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_1_0_1_0t(target("spirv.Image", float, 1, 2, 1, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]]) -// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]] -// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0 -// CHECK: %[[W_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[W_VAL]] to float -// CHECK: store float %[[W_F]], ptr %[[W_PTR]] -// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]] -// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1 -// CHECK: %[[H_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[H_VAL]] to float -// CHECK: store float %[[H_F]], ptr %[[H_PTR]] -// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]] -// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2 -// CHECK: %[[L_F:.*]] = uitofp reassoc nnan ninf nsz arcp afn i32 %[[L_VAL]] to float -// CHECK: store float %[[L_F]], ptr %[[L_PTR]] diff --git a/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl new file mode 100644 index 0000000000000..34f704043e55e --- /dev/null +++ b/clang/test/SemaHLSL/Resources/RWTexture2D-mips-errors.hlsl @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -verify %s + +// RWTexture2D has no mips view (contrast with Texture2D-mips-errors.hlsl, +// which exercises private/protected mips_type on Texture2D). + +TEXTURE t; + +void test_no_mips_member() { + // expected-error@+1 {{no member named 'mips' in 'hlsl::RWTexture2D}} + (void)t.mips; +} + +void test_no_mips_type() { + // expected-error@+1 {{no type named 'mips_type' in 'hlsl::RWTexture2D}} + TEXTURE::mips_type a; + + // expected-error@+1 {{no type named 'mips_slice_type' in 'hlsl::RWTexture2D}} + TEXTURE::mips_slice_type b; +} diff --git a/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl new file mode 100644 index 0000000000000..61c7497217284 --- /dev/null +++ b/clang/test/SemaHLSL/Resources/RWTexture2D-unsupported-methods-errors.hlsl @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -verify %s + +// SRV-style texture methods are not available on RWTexture2D or RWTexture2DArray (UAV). + +TEXTURE Tex; +SamplerState Samp; +SamplerComparisonState SampCmp; + +void main(float2 uv) { + int2 offset = int2(0, 0); + float compare = 0.5f; + + // expected-error@+1 {{no member named 'SampleLevel' in 'hlsl::RWTexture2D}} + Tex.SampleLevel(Samp, uv, 0.0f); + // expected-error@+1 {{no member named 'SampleBias' in 'hlsl::RWTexture2D}} + Tex.SampleBias(Samp, uv, 0.0f); + // expected-error@+1 {{no member named 'SampleGrad' in 'hlsl::RWTexture2D}} + Tex.SampleGrad(Samp, uv, float2(0), float2(0)); + // expected-error@+1 {{no member named 'SampleCmp' in 'hlsl::RWTexture2D}} + Tex.SampleCmp(SampCmp, uv, compare); + // expected-error@+1 {{no member named 'SampleCmpLevelZero' in 'hlsl::RWTexture2D}} + Tex.SampleCmpLevelZero(SampCmp, uv, compare); + + // expected-error@+1 {{no member named 'Gather' in 'hlsl::RWTexture2D}} + Tex.Gather(Samp, uv); + // expected-error@+1 {{no member named 'GatherRed' in 'hlsl::RWTexture2D}} + Tex.GatherRed(Samp, uv); + // expected-error@+1 {{no member named 'GatherGreen' in 'hlsl::RWTexture2D}} + Tex.GatherGreen(Samp, uv, offset); + // expected-error@+1 {{no member named 'GatherCmp' in 'hlsl::RWTexture2D}} + Tex.GatherCmp(SampCmp, uv, compare); + + // expected-error@+1 {{no member named 'CalculateLevelOfDetail' in 'hlsl::RWTexture2D}} + (void)Tex.CalculateLevelOfDetail(Samp, uv); + // expected-error@+1 {{no member named 'CalculateLevelOfDetailUnclamped' in 'hlsl::RWTexture2D}} + (void)Tex.CalculateLevelOfDetailUnclamped(Samp, uv); +} diff --git a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl index c6886f975ea59..6a6c2b1e2da4e 100644 --- a/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl +++ b/clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl @@ -1,6 +1,8 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=Texture2D -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=Texture2DArray -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -DTEXTURE=RWTexture2D -verify %s -Texture2D tex; +TEXTURE tex; void main() { uint u_w, u_h, u_l; diff --git a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl similarity index 52% rename from clang/test/SemaHLSL/Texture2D-Load-errors.hlsl rename to clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl index 9027c2ea144b8..88e1f81d07094 100644 --- a/clang/test/SemaHLSL/Texture2D-Load-errors.hlsl +++ b/clang/test/SemaHLSL/Resources/Texture2D-Load-errors.hlsl @@ -1,6 +1,18 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify %s - -Texture2D t; +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=Texture2D -DARRAYED=0 -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=Texture2DArray -DARRAYED=1 -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -DTEXTURE=RWTexture2D -DARRAYED=0 -verify %s + +#if ARRAYED +#define ITY int4 +#define FTY float4 +#define ZEROS 0, 0 +#else +#define ITY int3 +#define FTY float3 +#define ZEROS 0 +#endif + +TEXTURE t; float4 test_too_few_args() { return t.Load(); // expected-error {{no matching member function for call to 'Load'}} @@ -9,35 +21,38 @@ float4 test_too_few_args() { } float4 test_too_many_args(int2 loc) { - return t.Load(int3(loc, 0), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} + return t.Load(ITY(loc, ZEROS), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but 3 arguments were provided}} } float4 test_invalid_coord_type(float2 loc) { - return t.Load(float3(loc, 0)); // expected-warning {{implicit conversion turns floating-point number into integer: 'float3' (aka 'vector') to 'vector'}} + return t.Load(FTY(loc, ZEROS)); // expected-warning {{implicit conversion turns floating-point number into integer: }} } float4 test_invalid_offset_type(int2 loc, float2 offset) { - return t.Load(int3(loc, 0), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector'}} + return t.Load(ITY(loc, ZEROS), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector' (vector of 2 'int' values)}} } float4 test_invalid_location_count(int2 loc) { return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to 'vector' (vector of 3 'int' values) for 1st argument}} + // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to }} // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} } float4 test_truncated_location_count(int4 loc) { +#if ARRAYED + return t.Load(loc); // no warning expected for array textures which take an int4 argument +#else return t.Load(loc); // expected-warning {{implicit conversion truncates vector: 'int4' (aka 'vector') to 'vector' (vector of 3 'int' values)}} +#endif } -float4 test_splatted_offset_count(int3 loc, int offset) { +float4 test_splatted_offset_count(ITY loc, int offset) { // No errors expected. The vector will be generated by splatting `offset`. return t.Load(loc, offset); } - float4 test_truncated_offset_count(int2 loc, int3 offset) { - return t.Load(int3(loc, 0), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} + return t.Load(ITY(loc, ZEROS), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} } diff --git a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl b/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl deleted file mode 100644 index 36427aab0e604..0000000000000 --- a/clang/test/SemaHLSL/Texture2DArray-Load-errors.hlsl +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -finclude-default-header -verify %s - -Texture2DArray t; - -float4 test_too_few_args() { - return t.Load(); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but no arguments were provided}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 0 were provided}} -} - -float4 test_too_many_args(int3 loc) { - return t.Load(int4(loc, 0), int2(1, 1), 1); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}} - // expected-note@*:* {{candidate function not viable: requires single argument 'Location', but 3 arguments were provided}} -} - -float4 test_invalid_coord_type(float3 loc) { - return t.Load(float4(loc, 0)); // expected-warning {{implicit conversion turns floating-point number into integer: 'float4' (aka 'vector') to 'vector'}} -} - -float4 test_invalid_offset_type(int3 loc, float2 offset) { - return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion turns floating-point number into integer: 'float2' (aka 'vector') to 'vector'}} -} - -float4 test_invalid_location_count(int2 loc) { - return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int2' (aka 'vector') to 'vector' (vector of 4 'int' values) for 1st argument}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} -} - -float4 test_short_location_count(int3 loc) { - return t.Load(loc); // expected-error {{no matching member function for call to 'Load'}} - // expected-note@*:* {{candidate function not viable: no known conversion from 'int3' (aka 'vector') to 'vector' (vector of 4 'int' values) for 1st argument}} - // expected-note@*:* {{candidate function not viable: requires 2 arguments, but 1 was provided}} -} - -float4 test_splatted_offset_count(int4 loc, int offset) { - // No errors expected. The vector will be generated by splatting `offset`. - return t.Load(loc, offset); -} - -float4 test_truncated_offset_count(int3 loc, int3 offset) { - return t.Load(int4(loc, 0), offset); // expected-warning {{implicit conversion truncates vector: 'int3' (aka 'vector') to 'vector' (vector of 2 'int' values)}} -} From 09fbfb5d3e965010ed87b84f7d7e88f9024b9ccc Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 10 Jul 2026 09:13:13 +0100 Subject: [PATCH 088/125] [VPlan] Remove FoldTail argument for createConsecutiveVecPtr (NFC). (#208550) The argument is no longer needed now that we can look up the information directly from VPlan. --- llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h | 3 +-- llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 3 +-- llvm/lib/Transforms/Vectorize/VPlan.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index 1e48aea0fc061..e4cfdecfb1acf 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -527,8 +527,7 @@ class VPBuilder { /// with element type \p SourceElementTy. VPSingleDefRecipe *createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, - bool Reverse, bool FoldTail, - DebugLoc DL); + bool Reverse, DebugLoc DL); VPWidenMemIntrinsicRecipe *createWidenMemIntrinsic( Intrinsic::ID VectorIntrinsicID, ArrayRef CallArguments, diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 6e94d36cd8fb1..a4aae2651ee4c 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -6199,8 +6199,7 @@ VPRecipeBase *VPRecipeBuilder::tryToWidenMemory(VPInstruction *VPI, if (Consecutive) { Builder.setInsertPoint(VPI); Ptr = Builder.createConsecutiveVectorPointer(Ptr, getLoadStoreType(I), - Reverse, Plan.hasTailFolded(), - VPI->getDebugLoc()); + Reverse, VPI->getDebugLoc()); } if (Reverse && Mask) diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 2088f91657289..7d69b3453cba9 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -1667,8 +1667,7 @@ bool LoopVectorizationPlanner::getDecisionAndClampRange( VPSingleDefRecipe * VPBuilder::createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, - bool Reverse, bool FoldTail, - DebugLoc DL) { + bool Reverse, DebugLoc DL) { VPlan &Plan = getPlan(); GEPNoWrapFlags Flags = vputils::getGEPFlagsForPtr(Ptr); if (Reverse) { @@ -1676,8 +1675,9 @@ VPBuilder::createConsecutiveVectorPointer(VPValue *Ptr, Type *SourceElementTy, // original scalar loop: drop the GEP no-wrap flags in this case. Otherwise // preserve existing flags without no-unsigned-wrap, as we will emit // negative indices. - GEPNoWrapFlags ReverseFlags = - FoldTail ? GEPNoWrapFlags::none() : Flags.withoutNoUnsignedWrap(); + GEPNoWrapFlags ReverseFlags = Plan.hasTailFolded() + ? GEPNoWrapFlags::none() + : Flags.withoutNoUnsignedWrap(); return tryInsertInstruction(new VPVectorEndPointerRecipe( Ptr, &Plan.getVF(), SourceElementTy, /*Stride=*/-1, ReverseFlags, DL)); } From 380c581b724d0777ee73dce8fb09858d015439e1 Mon Sep 17 00:00:00 2001 From: Jan Patrick Lehr Date: Fri, 10 Jul 2026 10:14:13 +0200 Subject: [PATCH 089/125] [Offload] Fix warn-unused function (#208642) Unblock the `-Werror` build in pre-merge by adding a few [[maybe_unused]] here and there. --- offload/plugins-nextgen/amdgpu/src/rtl.cpp | 4 ++-- offload/plugins-nextgen/common/include/OffloadError.h | 4 ++-- offload/plugins-nextgen/common/include/PluginInterface.h | 3 ++- offload/plugins-nextgen/host/src/rtl.cpp | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp index e6ceeea5331d1..f1caee0c4c1e2 100644 --- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp @@ -126,8 +126,8 @@ static hsa_status_t iterate(IterFuncTy Func, IterFuncArgTy FuncArg, /// use this function directly but the specialized ones below instead. template -static hsa_status_t iterate(IterFuncTy Func, IterFuncArgTy FuncArg, - CallbackTy Cb) { +[[maybe_unused]] static hsa_status_t +iterate(IterFuncTy Func, IterFuncArgTy FuncArg, CallbackTy Cb) { auto L = [](Elem1Ty Elem1, Elem2Ty Elem2, void *Data) -> hsa_status_t { CallbackTy *Unwrapped = static_cast(Data); return (*Unwrapped)(Elem1, Elem2); diff --git a/offload/plugins-nextgen/common/include/OffloadError.h b/offload/plugins-nextgen/common/include/OffloadError.h index f2a56d2c41117..3d0ceb400c99c 100644 --- a/offload/plugins-nextgen/common/include/OffloadError.h +++ b/offload/plugins-nextgen/common/include/OffloadError.h @@ -49,8 +49,8 @@ class OffloadError : public llvm::ErrorInfo { /// Create an Offload error. template -static llvm::Error createOffloadError(error::ErrorCode Code, const char *ErrFmt, - ArgsTy... Args) { +[[maybe_unused]] static llvm::Error +createOffloadError(error::ErrorCode Code, const char *ErrFmt, ArgsTy... Args) { std::string Buffer; llvm::raw_string_ostream(Buffer) << llvm::format(ErrFmt, Args...); return llvm::make_error(Code, Buffer); diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h index 400605763b365..2a23d319fff49 100644 --- a/offload/plugins-nextgen/common/include/PluginInterface.h +++ b/offload/plugins-nextgen/common/include/PluginInterface.h @@ -98,7 +98,8 @@ inline Error error(error::ErrorCode Code, Error &&OtherError, /// the plugin-specific code. /// TODO: Refactor this, must be defined individually by each plugin. template -static Error check(int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args); +[[maybe_unused]] static Error check(int32_t ErrorCode, const char *ErrFmt, + ArgsTy... Args); } // namespace Plugin /// Class that wraps the __tgt_async_info to simply its usage. In case the diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp index 505494095a10a..a5d4ffd003fd7 100644 --- a/offload/plugins-nextgen/host/src/rtl.cpp +++ b/offload/plugins-nextgen/host/src/rtl.cpp @@ -558,7 +558,8 @@ struct GenELF64PluginTy final : public GenericPluginTy { }; template -static Error Plugin::check(int32_t Code, const char *ErrMsg, ArgsTy... Args) { +[[maybe_unused]] static Error Plugin::check(int32_t Code, const char *ErrMsg, + ArgsTy... Args) { if (Code == 0) return Plugin::success(); From 445d6c31c829fd01adf837ea50f19dbe4f7bd9ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Warzy=C5=84ski?= Date: Fri, 10 Jul 2026 09:24:58 +0100 Subject: [PATCH 090/125] [CIR][AArc64] Add lowering for fp16 intrinsics (sqrt + max + min) (#207786) This PR adds lowering for the following intrinsic groups: * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-square-root-1 * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#maximum-1O * https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#markdown-toc-minimum-1 It also moves the corresponding tests from: * clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c to: * clang/test/CodeGen/AArch64/neon/fullfp16.c The lowering follows the existing implementation in CodeGen/TargetBuiltins/ARM.cpp. --- .../lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp | 41 ++++++------- clang/test/CodeGen/AArch64/neon/fullfp16.c | 61 ++++++++++++++++++- .../CodeGen/AArch64/v8.2a-fp16-intrinsics.c | 35 ----------- 3 files changed, 80 insertions(+), 57 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp index dfb5ace82bb06..2608aaf780591 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp @@ -2869,22 +2869,20 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, if (cir::isFPOrVectorOfFPType(ty)) intrName = "aarch64.neon.fmax"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vmaxh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vmaxh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmax", halfTy, ops); + } case NEON::BI__builtin_neon_vmin_v: case NEON::BI__builtin_neon_vminq_v: intrName = usgn ? "aarch64.neon.umin" : "aarch64.neon.smin"; if (cir::isFPOrVectorOfFPType(ty)) intrName = "aarch64.neon.fmin"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vminh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vminh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmin", halfTy, ops); + } case NEON::BI__builtin_neon_vabd_v: case NEON::BI__builtin_neon_vabdq_v: intrName = usgn ? "aarch64.neon.uabd" : "aarch64.neon.sabd"; @@ -2917,16 +2915,18 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vminnmq_v: intrName = "aarch64.neon.fminnm"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vminnmh_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vminnmh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fminnm", halfTy, ops); + } case NEON::BI__builtin_neon_vmaxnm_v: case NEON::BI__builtin_neon_vmaxnmq_v: intrName = "aarch64.neon.fmaxnm"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vmaxnmh_f16: + case NEON::BI__builtin_neon_vmaxnmh_f16: { + auto halfTy = builder.getFp16Ty(); + return builder.emitIntrinsicCallOp(loc, "aarch64.neon.fmaxnm", halfTy, ops); + } case NEON::BI__builtin_neon_vrecpss_f32: case NEON::BI__builtin_neon_vrecpsd_f64: cgm.errorNYI(expr->getSourceRange(), @@ -3106,11 +3106,10 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned builtinID, const CallExpr *expr, case NEON::BI__builtin_neon_vpminnmq_v: intrName = "aarch64.neon.fminnmp"; return emitNeonCall(cgm, builder, {ty, ty}, ops, intrName, ty, loc); - case NEON::BI__builtin_neon_vsqrth_f16: - cgm.errorNYI(expr->getSourceRange(), - std::string("unimplemented AArch64 builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); - return mlir::Value{}; + case NEON::BI__builtin_neon_vsqrth_f16: { + auto halfTy = builder.getFp16Ty(); + return emitCallMaybeConstrainedBuiltin(builder, loc, "sqrt", {halfTy}, ops); + } case NEON::BI__builtin_neon_vsqrt_v: case NEON::BI__builtin_neon_vsqrtq_v: assert(!cir::MissingFeatures::emitConstrainedFPCall()); diff --git a/clang/test/CodeGen/AArch64/neon/fullfp16.c b/clang/test/CodeGen/AArch64/neon/fullfp16.c index cd93d30e7d2ae..71a5a7d98eb83 100644 --- a/clang/test/CodeGen/AArch64/neon/fullfp16.c +++ b/clang/test/CodeGen/AArch64/neon/fullfp16.c @@ -34,7 +34,7 @@ #include //===------------------------------------------------------===// -// 2.5.1.1. Addition +// 2.5.1.5. Addition //===------------------------------------------------------===// // ALL-LABEL: @test_vaddh_f16( float16_t test_vaddh_f16(float16_t a, float16_t b) { @@ -85,6 +85,52 @@ float16_t test_vdivh_f16(float16_t a, float16_t b) { return vdivh_f16(a, b); } +//===------------------------------------------------------===// +// 2.5.1.7. Maximum +//===------------------------------------------------------===// +// ALL-LABEL: test_vmaxh_f16 +float16_t test_vmaxh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmax" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmax.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MAX]] + return vmaxh_f16(a, b); +} + +// ALL-LABEL: test_vmaxnmh_f16 +float16_t test_vmaxnmh_f16(float16_t a, float16_t b) { +// CIR: cir.call_llvm_intrinsic "aarch64.neon.fmaxnm" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmaxnm.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MAX]] + return vmaxnmh_f16(a, b); +} + +//===------------------------------------------------------===// +// 2.5.1.8. Mimimum +//===------------------------------------------------------===// +// ALL-LABEL: test_vminh_f16 +float16_t test_vminh_f16(float16_t a, float16_t b) { +// CIR: {{%.*}} = cir.call_llvm_intrinsic "aarch64.neon.fmin" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MIN:%.*]] = call half @llvm.aarch64.neon.fmin.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MIN]] + return vminh_f16(a, b); +} + +// ALL-LABEL: test_vminnmh_f16 +float16_t test_vminnmh_f16(float16_t a, float16_t b) { +// CIR: cir.call_llvm_intrinsic "aarch64.neon.fminnm" + +// LLVM-SAME: half {{.*}} [[A:%.]], half {{.*}} [[B:%.]]) {{.*}} { +// LLVM: [[MIN:%.*]] = call half @llvm.aarch64.neon.fminnm.f16(half [[A]], half [[B]]) +// LLVM: ret half [[MIN]] + return vminnmh_f16(a, b); +} + //===------------------------------------------------------===// // 2.5.2.1. Bitwise equal to zero //===------------------------------------------------------===// @@ -260,6 +306,19 @@ float16_t test_vrndxh_f16(float16_t a) { return vrndxh_f16(a); } +//===------------------------------------------------------===// +// 2.5.1.4. Square root +//===------------------------------------------------------===// +// ALL-LABEL: test_vsqrth_f16 +float16_t test_vsqrth_f16(float16_t a) { +// CIR: cir.call_llvm_intrinsic "sqrt" + +// LLVM-SAME: half{{.*}} [[A:%.*]]) +// LLVM: [[SQR:%.*]] = call half @llvm.sqrt.f16(half [[A]]) +// LLVM: ret half [[SQR]] + return vsqrth_f16(a); +} + //===------------------------------------------------------===// // 2.5.4.1. Negate //===------------------------------------------------------===// diff --git a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c index ad4a0e5eb7275..d519e4138adbf 100644 --- a/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c +++ b/clang/test/CodeGen/AArch64/v8.2a-fp16-intrinsics.c @@ -291,13 +291,6 @@ uint64_t test_vcvtph_u64_f16 (float16_t a) { return vcvtph_u64_f16(a); } -// CHECK-LABEL: test_vsqrth_f16 -// CHECK: [[SQR:%.*]] = call half @llvm.sqrt.f16(half %a) -// CHECK: ret half [[SQR]] -float16_t test_vsqrth_f16(float16_t a) { - return vsqrth_f16(a); -} - // CHECK-LABEL: test_vcageh_f16 // CHECK: [[FACG:%.*]] = call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b) // CHECK: [[RET:%.*]] = trunc i32 [[FACG]] to i16 @@ -458,34 +451,6 @@ int64_t test_vcvth_n_u64_f16(float16_t a) { return vcvth_n_u64_f16(a, 1); } -// CHECK-LABEL: test_vmaxh_f16 -// CHECK: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmax.f16(half %a, half %b) -// CHECK: ret half [[MAX]] -float16_t test_vmaxh_f16(float16_t a, float16_t b) { - return vmaxh_f16(a, b); -} - -// CHECK-LABEL: test_vmaxnmh_f16 -// CHECK: [[MAX:%.*]] = call half @llvm.aarch64.neon.fmaxnm.f16(half %a, half %b) -// CHECK: ret half [[MAX]] -float16_t test_vmaxnmh_f16(float16_t a, float16_t b) { - return vmaxnmh_f16(a, b); -} - -// CHECK-LABEL: test_vminh_f16 -// CHECK: [[MIN:%.*]] = call half @llvm.aarch64.neon.fmin.f16(half %a, half %b) -// CHECK: ret half [[MIN]] -float16_t test_vminh_f16(float16_t a, float16_t b) { - return vminh_f16(a, b); -} - -// CHECK-LABEL: test_vminnmh_f16 -// CHECK: [[MIN:%.*]] = call half @llvm.aarch64.neon.fminnm.f16(half %a, half %b) -// CHECK: ret half [[MIN]] -float16_t test_vminnmh_f16(float16_t a, float16_t b) { - return vminnmh_f16(a, b); -} - // CHECK-LABEL: test_vmulxh_f16 // CHECK: [[MUL:%.*]] = call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b) // CHECK: ret half [[MUL]] From 6ec6a777acdadbb8ba184e6c33016ae156c1f819 Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Fri, 10 Jul 2026 10:25:41 +0200 Subject: [PATCH 091/125] [NFC][SPIR-V] Remove unused GR parameter from vector elt legalizers (#208495) --- llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp index b39806b5848e1..6ddc4c789a079 100644 --- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp @@ -562,8 +562,8 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) { verify(*ST.getInstrInfo()); } -static bool legalizeExtractVectorElt(LegalizerHelper &Helper, MachineInstr &MI, - SPIRVGlobalRegistry *GR) { +static bool legalizeExtractVectorElt(LegalizerHelper &Helper, + MachineInstr &MI) { MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); @@ -577,8 +577,7 @@ static bool legalizeExtractVectorElt(LegalizerHelper &Helper, MachineInstr &MI, return true; } -static bool legalizeInsertVectorElt(LegalizerHelper &Helper, MachineInstr &MI, - SPIRVGlobalRegistry *GR) { +static bool legalizeInsertVectorElt(LegalizerHelper &Helper, MachineInstr &MI) { MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; Register DstReg = MI.getOperand(0).getReg(); Register SrcReg = MI.getOperand(1).getReg(); @@ -726,9 +725,9 @@ bool SPIRVLegalizerInfo::legalizeCustom( case TargetOpcode::G_BITCAST: return legalizeBitcast(Helper, MI); case TargetOpcode::G_EXTRACT_VECTOR_ELT: - return legalizeExtractVectorElt(Helper, MI, GR); + return legalizeExtractVectorElt(Helper, MI); case TargetOpcode::G_INSERT_VECTOR_ELT: - return legalizeInsertVectorElt(Helper, MI, GR); + return legalizeInsertVectorElt(Helper, MI); case TargetOpcode::G_INTRINSIC: case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS: return legalizeIntrinsic(Helper, MI); From 3c59a212da58808263457c98a1df0dfd77bbb773 Mon Sep 17 00:00:00 2001 From: Raphael Isemann Date: Fri, 10 Jul 2026 09:29:06 +0100 Subject: [PATCH 092/125] [lldb][test] Add a new test for integer types (#208441) This is a new modern test for integer types that replaces the test logic from `API/types` test that is about to be deleted. See also #208402 assisted-by: claude --- .../API/lang/cpp/builtin_types/int/Makefile | 3 ++ .../cpp/builtin_types/int/TestIntTypes.py | 43 +++++++++++++++++++ .../API/lang/cpp/builtin_types/int/main.cpp | 23 ++++++++++ 3 files changed, 69 insertions(+) create mode 100644 lldb/test/API/lang/cpp/builtin_types/int/Makefile create mode 100644 lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py create mode 100644 lldb/test/API/lang/cpp/builtin_types/int/main.cpp diff --git a/lldb/test/API/lang/cpp/builtin_types/int/Makefile b/lldb/test/API/lang/cpp/builtin_types/int/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py b/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py new file mode 100644 index 0000000000000..932dd17192163 --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/TestIntTypes.py @@ -0,0 +1,43 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCase(TestBase): + def test(self): + """Check the types and values of all integer-typed variables.""" + self.build_and_run() + + self.expect_var_path("the_short", type="short", value="-31987") + self.expect_expr("the_short", result_type="short", result_value="-31987") + + self.expect_var_path("the_unsigned_short", type="unsigned short", value="65000") + self.expect_expr( + "the_unsigned_short", result_type="unsigned short", result_value="65000" + ) + + self.expect_var_path("the_int", type="int", value="-1100110") + self.expect_expr("the_int", result_type="int", result_value="-1100110") + + self.expect_var_path( + "the_unsigned_int", type="unsigned int", value="4000000000" + ) + self.expect_expr( + "the_unsigned_int", result_type="unsigned int", result_value="4000000000" + ) + + # Check edge-case values: smallest, largest, zero and -1. + self.expect_var_path("short_min", type="short", value="-32768") + self.expect_var_path("short_max", type="short", value="32767") + self.expect_var_path("short_zero", type="short", value="0") + self.expect_var_path("short_neg_one", type="short", value="-1") + self.expect_var_path("ushort_zero", type="unsigned short", value="0") + self.expect_var_path("ushort_max", type="unsigned short", value="65535") + + self.expect_var_path("int_min", type="int", value="-2147483648") + self.expect_var_path("int_max", type="int", value="2147483647") + self.expect_var_path("int_zero", type="int", value="0") + self.expect_var_path("int_neg_one", type="int", value="-1") + self.expect_var_path("uint_zero", type="unsigned int", value="0") + self.expect_var_path("uint_max", type="unsigned int", value="4294967295") diff --git a/lldb/test/API/lang/cpp/builtin_types/int/main.cpp b/lldb/test/API/lang/cpp/builtin_types/int/main.cpp new file mode 100644 index 0000000000000..c20d9e24889ba --- /dev/null +++ b/lldb/test/API/lang/cpp/builtin_types/int/main.cpp @@ -0,0 +1,23 @@ +int main() { + short the_short = -31987; + unsigned short the_unsigned_short = 65000; + int the_int = -1100110; + unsigned int the_unsigned_int = 4000000000u; + + // Edge-case values: smallest, largest, zero and -1. + short short_min = -32768; + short short_max = 32767; + short short_zero = 0; + short short_neg_one = -1; + unsigned short ushort_zero = 0; + unsigned short ushort_max = 65535; + + int int_min = -2147483647 - 1; + int int_max = 2147483647; + int int_zero = 0; + int int_neg_one = -1; + unsigned int uint_zero = 0; + unsigned int uint_max = 4294967295u; + + return 0; // break here +} From c93aefbd97d8a8fb76e6351d214724a57294c999 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 10 Jul 2026 04:32:27 -0400 Subject: [PATCH 093/125] [libc++] Remove diagnostic about _LIBCPP_ABI_NO_ITERATOR_BASES (#208460) This was slated for removal in LLVM 22 but we hadn't removed it yet. --- libcxx/include/__configuration/abi.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index 8a34ebcc7bb90..85a524b1af334 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -88,15 +88,6 @@ # endif #endif -// TODO(LLVM 22): Remove this check -#if defined(_LIBCPP_ABI_NO_ITERATOR_BASES) && !defined(_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER) -# ifndef _LIBCPP_ONLY_NO_ITERATOR_BASES -# error "You probably want to define _LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER. This has been split out from" \ - " _LIBCPP_ABI_NO_ITERATOR_BASES to allow only removing the second iterator member, since they aren't really related." \ - "If you actually want this ABI configuration, please define _LIBCPP_ONLY_NO_ITERATOR_BASES instead." -# endif -#endif - // We had some bugs where we use [[no_unique_address]] together with construct_at, // which causes UB as the call on construct_at could write to overlapping subobjects // From 0faf45cd652e488de348ff237f0666ca0751de61 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Fri, 10 Jul 2026 04:33:36 -0400 Subject: [PATCH 094/125] [libc++] Rename the macro for the LLVM 18 ABI tag used in ranges (#208464) We typically use macros like _LIBCPP_ABI_XYZ for ABI settings that can be configured by the user. Since _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS is not one of those, rename it to make it clearer it's an ABI tag attribute. As a drive-by remove the definition in the frozen C++03 config header since it should never be needed (Ranges are not provided in C++03). --- libcxx/include/__configuration/abi.h | 2 +- libcxx/include/__cxx03/__configuration/abi.h | 10 ---------- libcxx/include/__ranges/chunk_by_view.h | 2 +- libcxx/include/__ranges/drop_while_view.h | 2 +- libcxx/include/__ranges/filter_view.h | 2 +- libcxx/include/__ranges/repeat_view.h | 2 +- libcxx/include/__ranges/single_view.h | 2 +- libcxx/include/__ranges/take_while_view.h | 2 +- libcxx/include/__ranges/transform_view.h | 2 +- 9 files changed, 8 insertions(+), 18 deletions(-) diff --git a/libcxx/include/__configuration/abi.h b/libcxx/include/__configuration/abi.h index 85a524b1af334..757ba69cb17b4 100644 --- a/libcxx/include/__configuration/abi.h +++ b/libcxx/include/__configuration/abi.h @@ -96,7 +96,7 @@ // // To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions. // The macro below is used for all classes whose ABI have changed as part of fixing these bugs. -#define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua"))) +#define _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG __attribute__((__abi_tag__("llvm18_nua"))) // [[msvc::no_unique_address]] seems to mostly affect empty classes, so the padding scheme for Itanium doesn't work. #if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING) diff --git a/libcxx/include/__cxx03/__configuration/abi.h b/libcxx/include/__cxx03/__configuration/abi.h index 81dd5b1c59610..56ebe520f65a0 100644 --- a/libcxx/include/__cxx03/__configuration/abi.h +++ b/libcxx/include/__cxx03/__configuration/abi.h @@ -121,16 +121,6 @@ # endif #endif -// We had some bugs where we use [[no_unique_address]] together with construct_at, -// which causes UB as the call on construct_at could write to overlapping subobjects -// -// https://github.com/llvm/llvm-project/issues/70506 -// https://github.com/llvm/llvm-project/issues/70494 -// -// To fix the bug we had to change the ABI of some classes to remove [[no_unique_address]] under certain conditions. -// The macro below is used for all classes whose ABI have changed as part of fixing these bugs. -#define _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS __attribute__((__abi_tag__("llvm18_nua"))) - // Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's // within the bounds of the original container and asserts it on every dereference. // diff --git a/libcxx/include/__ranges/chunk_by_view.h b/libcxx/include/__ranges/chunk_by_view.h index 8007f76f0c1e6..07824d11e79be 100644 --- a/libcxx/include/__ranges/chunk_by_view.h +++ b/libcxx/include/__ranges/chunk_by_view.h @@ -54,7 +54,7 @@ namespace ranges { template , iterator_t<_View>> _Pred> requires view<_View> && is_object_v<_Pred> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_by_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG chunk_by_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; diff --git a/libcxx/include/__ranges/drop_while_view.h b/libcxx/include/__ranges/drop_while_view.h index ed5b91d99425f..caa24643b477f 100644 --- a/libcxx/include/__ranges/drop_while_view.h +++ b/libcxx/include/__ranges/drop_while_view.h @@ -48,7 +48,7 @@ namespace ranges { template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS drop_while_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG drop_while_view : public view_interface> { public: _LIBCPP_HIDE_FROM_ABI drop_while_view() requires default_initializable<_View> && default_initializable<_Pred> diff --git a/libcxx/include/__ranges/filter_view.h b/libcxx/include/__ranges/filter_view.h index 4612dc4a9ba1d..7ec53dac4a84f 100644 --- a/libcxx/include/__ranges/filter_view.h +++ b/libcxx/include/__ranges/filter_view.h @@ -54,7 +54,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { template > _Pred> requires view<_View> && is_object_v<_Pred> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS filter_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG filter_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_; diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index ae13af8761b89..48e8f70cc10c6 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -74,7 +74,7 @@ struct __fn; template requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> && (__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>)) -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG repeat_view : public view_interface> { friend struct views::__take::__fn; friend struct views::__drop::__fn; class __iterator; diff --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h index 213c507138e68..b86a8d6790b01 100644 --- a/libcxx/include/__ranges/single_view.h +++ b/libcxx/include/__ranges/single_view.h @@ -41,7 +41,7 @@ template template # endif requires is_object_v<_Tp> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS single_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG single_view : public view_interface> { _LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_; public: diff --git a/libcxx/include/__ranges/take_while_view.h b/libcxx/include/__ranges/take_while_view.h index f91dcfa95b9a5..0aee306807c8b 100644 --- a/libcxx/include/__ranges/take_while_view.h +++ b/libcxx/include/__ranges/take_while_view.h @@ -46,7 +46,7 @@ namespace ranges { template requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS take_while_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG take_while_view : public view_interface> { template class __sentinel; diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h index 1484be006e841..06ace86bbfafa 100644 --- a/libcxx/include/__ranges/transform_view.h +++ b/libcxx/include/__ranges/transform_view.h @@ -71,7 +71,7 @@ template template # endif requires __transform_view_constraints<_View, _Fn> -class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interface> { +class _LIBCPP_LLVM18_NO_UNIQUE_ADDRESS_ABI_TAG transform_view : public view_interface> { template class __iterator; template From c1d66b53568cac5262798ce730c2d94ca2f5bc7b Mon Sep 17 00:00:00 2001 From: Vlad Serebrennikov Date: Fri, 10 Jul 2026 12:39:08 +0400 Subject: [PATCH 095/125] [clang] Update C++ DR status page (#208641) --- clang/www/cxx_dr_status.html | 69 ++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index d1a260b07a0fa..af91ac559d274 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -21439,7 +21439,7 @@

C++ defect report implementation status

3089 [dcl.init.general] WP - const-default-constructible improperly handles std::meta::info + const-default-constructible improperly handles std::meta::info Unknown @@ -22149,38 +22149,38 @@

C++ defect report implementation status

Ambiguous lookup for type aliases in reflection Not resolved - + 3191 [dcl.ref] - open + tentatively ready Reference collapsing with pack indexing and splicing - Not resolved + Unknown 3192 [class.local] - open + tentatively ready Out-of-line definition of an enum member of a local class Not resolved 3193 [dcl.friend] - open + tentatively ready Missing restrictions and effects for friend declarations Not resolved 3194 [lex.pptoken] - open + tentatively ready Lexing of <=> Not resolved 3195 [expr.const.core] - open + tentatively ready Starting the lifetime of a runtime object during constant evaluation Not resolved @@ -22194,7 +22194,7 @@

C++ defect report implementation status

3197 [diff.basic] - open + review Relaxed requirements for integer representations Not resolved @@ -22208,9 +22208,58 @@

C++ defect report implementation status

3199 [cpp.predefined] - open + tentatively ready Missing predefined macros for chart16_t and char32_t Not resolved + + + 3200 + [dcl.type.cv] + tentatively ready + Qualified pointer pointing to unqualified object + Not resolved + + + 3201 + [dcl.init.general] + tentatively ready + Zero- and default-initialization of cv-qualified std::meta::info + Not resolved + + + 3202 + [basic.fundamental] + open + Status of const std::meta::info + Not resolved + + + 3203 + [dcl.init.general] + open + Initialization of signed or unsigned char arrays from string-literal + Not resolved + + + 3204 + [expr.call] + open + Restrictions on arguments for ellipsis parameter + Not resolved + + + 3205 + [lex.pptoken] + review + Prefer header-name over user-defined-string-literal + Not resolved + + + 3206 + [class.local] + open + Scattered definition of "local class" + Not resolved From 24ce77ea005c1ef49d3552cbba74033d2662a0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= Date: Fri, 10 Jul 2026 10:42:30 +0200 Subject: [PATCH 096/125] [Clang][OpenMP] Fix `if` clause not affecting `teams` construct on host (#207444) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In #205345, it was discovered that the `if` clause for the `teams` construct does not actually create a serial league when the code is built with Clang. Looking at the emitted IR, no call to `__kmpc_push_num_teams` was added for an `if` clause. Hence, `__kmpc_fork_teams` always created the number of teams specified via the `num_teams` clause, or the _nteams-var_ ICV. During `emitCommonOMPTeamsDirective`, only the `num_teams` and `thread_limit` clauses were checked, whereas the `if` clause was missing. To fix the missing code, check for an `if` clause mapped to `teams` or `unknown`. If the clause is present, and false, emit `__kmpc_push_num_teams` with the number of teams set to 1. The `thread_limit` clause is unaffected. Otherwise, stick to the existing implementation and only call `__kmpc_push_num_teams` if `num_teams` or `thread_limit` are set. This only applies for OpenMP v5.2 and newer. Earlier OpenMP versions did not support the `if` clause for the `teams` construct, hence should continue to emit a number of teams based on attached `num_teams` and `thread_limit` clauses, or the _nteams-var_ ICV. This fix also only affects host-side execution, as `__kmpc_push_num_teams` is a no-op for offloaded code. For offloaded code, the number of leagues is set during the call to `__tgt_target_kernel`, whose passed arguments are unchanged. Closes #205345 --------- Signed-off-by: Jan André Reuter Signed-off-by: Jan André Reuter --- clang/lib/CodeGen/CGStmtOpenMP.cpp | 49 +- ..._parallel_for_simd_if_openmp52_codegen.cpp | 12098 +++++++++++++++ ..._parallel_for_simd_if_openmp52_codegen.cpp | 12190 ++++++++++++++++ 3 files changed, 24329 insertions(+), 8 deletions(-) create mode 100644 clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp create mode 100644 clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 88f698f38cce0..18524a7c32b7a 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -7366,17 +7366,50 @@ static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, CGF, S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); - const auto *NT = S.getSingleClause(); - const auto *TL = S.getSingleClause(); - if (NT || TL) { - const Expr *NumTeams = NT ? NT->getNumTeams().front() : nullptr; - const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + OMPTeamsScope Scope(CGF, S); + auto ParallelLeague = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + const auto *NT = S.getSingleClause(); + const auto *TL = S.getSingleClause(); + if (NT || TL) { + const Expr *NumTeams = NT ? NT->getNumTeams().front() : nullptr; + const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + + CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, + S.getBeginLoc()); + } + }; - CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, - S.getBeginLoc()); + const Expr *IfCond = nullptr; + for (const auto *C : S.getClausesOfKind()) { + if (C->getNameModifier() == OMPD_unknown || + C->getNameModifier() == OMPD_teams) { + IfCond = C->getCondition(); + break; + } + } + if (IfCond && CGF.CGM.getLangOpts().OpenMP >= 52) { + auto SerialLeague = [&S](CodeGenFunction &CGF, PrePostActionTy &) { + // OpenMP 5.2, 10.2, teams Construct + // When an if clause is present on a teams construct and the if clause + // expression evaluates to false, the number of created teams is one. + const llvm::APInt One(32, 1); + IntegerLiteral NumTeams( + CGF.getContext(), One, + CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0), + SourceLocation()); + // The thread_limit clause is unaffected by the if clause. + const auto *TL = S.getSingleClause(); + const Expr *ThreadLimit = TL ? TL->getThreadLimit().front() : nullptr; + CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, &NumTeams, ThreadLimit, + S.getBeginLoc()); + }; + CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ParallelLeague, + SerialLeague); + } else { + const RegionCodeGenTy ThenRCG(ParallelLeague); + ThenRCG(CGF); } - OMPTeamsScope Scope(CGF, S); llvm::SmallVector CapturedVars; CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn, diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp new file mode 100644 index 0000000000000..be3118906d197 --- /dev/null +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp @@ -0,0 +1,12098 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK3 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK7 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK7 + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK11 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK11 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK15 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK15 + +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void fn1(); +void fn2(); +void fn3(); +void fn4(); +void fn5(); +void fn6(); +void fn7(); + +int Arg; + +void gtid_test() { +#ifdef OMP5 +#pragma omp target teams distribute parallel for simd if(simd: true) nontemporal(Arg) +#else +#pragma omp target teams distribute parallel for simd +#endif // OMP5 + for (int i = 0; i < 100; i++) { + Arg = 0; + } + +#pragma omp target teams distribute parallel for simd if (parallel: false) + for(int i = 0 ; i < 100; i++) { + gtid_test(); + } +} + + +void gtid_test2() { +#ifdef OMP5 +#pragma omp target teams distribute parallel for simd if(simd: true) nontemporal(Arg) +#else +#pragma omp target teams distribute parallel for simd +#endif // OMP5 + for (int i = 0; i < 100; i++) { + Arg = 0; + } + +#pragma omp target teams distribute parallel for simd if (teams: false) + for(int i = 0 ; i < 100; i++) { + gtid_test2(); + } +} + + +template +int tmain(T Arg) { +#pragma omp target teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + fn1(); + } +#pragma omp target teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + fn2(); + } +#pragma omp target teams distribute parallel for simd if (parallel: Arg) + for(int i = 0 ; i < 100; i++) { + fn3(); + } +#pragma omp target teams distribute parallel for simd if (teams: Arg) + for(int i = 0 ; i < 100; i++) { + fn4(); + } + return 0; +} + +int main() { +#pragma omp target teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + + + fn5(); + } + +#pragma omp target teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + + + fn6(); + } + +#pragma omp target teams distribute parallel for simd if (Arg) + for(int i = 0 ; i < 100; i++) { + + + fn7(); + } + + return tmain(Arg); +} + + + + + + +// call void [[T_OUTLINE_FUN_3:@.+]]( + +#endif +// CHECK1-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK1-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK1-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK1-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK1-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK1-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK1-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK1-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@main +// CHECK1-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK1-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK1-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK1-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK1-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK1: omp_offload.failed9: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK1: omp_offload.cont10: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK1-NEXT: ret i32 [[CALL]] +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP48:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP53:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn6v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56:![0-9]+]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK1-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then4: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK1: omp_if.else5: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK1: omp.inner.for.cond6: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK1: omp.inner.for.body8: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK1-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK1: omp_if.then13: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK1-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK1: omp_if.else14: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_IF_END16]] +// CHECK1: omp_if.end16: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK1: omp.inner.for.inc17: +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK1: omp.inner.for.end19: +// CHECK1-NEXT: br label [[OMP_IF_END20]] +// CHECK1: omp_if.end20: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK1-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK1-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK1-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK1-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK1-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK1-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK1-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK1-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK1-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK1-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK1: omp_offload.failed8: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK1: omp_offload.cont9: +// CHECK1-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK1-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK1-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK1-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK1-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK1-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK1-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK1-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK1-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK1-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK1-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK1-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK1-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK1: omp_offload.failed21: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK1: omp_offload.cont22: +// CHECK1-NEXT: ret i32 0 +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP72:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP74:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn2v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP77:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP80:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK1-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP83:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP86:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK3-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK3-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK3-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21:![0-9]+]], !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK3-SAME: () #[[ATTR0]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK3-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK3-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK3-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK3-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@main +// CHECK3-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK3-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK3-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK3-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK3-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK3: omp_offload.failed9: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK3: omp_offload.cont10: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK3-NEXT: ret i32 [[CALL]] +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP54:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn6v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP56:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57:![0-9]+]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK3-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then4: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP58:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK3: omp_if.else5: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK3: omp.inner.for.cond6: +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK3-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK3: omp.inner.for.body8: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK3-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK3-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK3-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK3: omp_if.then13: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK3-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK3: omp_if.else14: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_IF_END16]] +// CHECK3: omp_if.end16: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK3: omp.inner.for.inc17: +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK3-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP60:![0-9]+]] +// CHECK3: omp.inner.for.end19: +// CHECK3-NEXT: br label [[OMP_IF_END20]] +// CHECK3: omp_if.end20: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK3-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP62:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP68:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK3-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK3-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK3-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK3-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK3-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK3-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK3-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK3-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK3-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK3: omp_offload.failed8: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK3: omp_offload.cont9: +// CHECK3-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK3-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK3-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK3-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK3-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK3-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK3-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK3-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK3-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK3-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK3-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK3-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK3-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK3-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK3: omp_offload.failed21: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK3: omp_offload.cont22: +// CHECK3-NEXT: ret i32 0 +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP70:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn2v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK3-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK5-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK5-SAME: () #[[ATTR0]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@main +// CHECK5-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn6v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK5-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK5: omp_if.then: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK5: omp_if.else: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK5: omp.inner.for.cond30: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK5: omp.inner.for.body32: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK5-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK5-NEXT: call void @_Z3fn7v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK5: omp.body.continue35: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK5: omp.inner.for.inc36: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK5: omp.inner.for.end38: +// CHECK5-NEXT: br label [[OMP_IF_END]] +// CHECK5: omp_if.end: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK5-NEXT: ret i32 [[CALL]] +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK5-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn2v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK5-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK5-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK5: omp.inner.for.cond38: +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK5-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK5: omp.inner.for.body40: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK5-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK5: omp.body.continue43: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK5: omp.inner.for.inc44: +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK5-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK5: omp.inner.for.end46: +// CHECK5-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK5-NEXT: ret i32 0 +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK7-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2:![0-9]+]], !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK7-SAME: () #[[ATTR0]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2]], !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP13:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@main +// CHECK7-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn6v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK7-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK7: omp_if.then: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK7: omp_if.else: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK7: omp.inner.for.cond30: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK7: omp.inner.for.body32: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK7-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK7-NEXT: call void @_Z3fn7v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK7: omp.body.continue35: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK7: omp.inner.for.inc36: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP23:![0-9]+]] +// CHECK7: omp.inner.for.end38: +// CHECK7-NEXT: br label [[OMP_IF_END]] +// CHECK7: omp_if.end: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK7-NEXT: ret i32 [[CALL]] +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK7-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn2v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK7-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK7-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK7: omp.inner.for.cond38: +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31:![0-9]+]] +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK7-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK7: omp.inner.for.body40: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK7-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK7: omp.body.continue43: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK7: omp.inner.for.inc44: +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK7-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP32:![0-9]+]] +// CHECK7: omp.inner.for.end46: +// CHECK7-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK7-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK9-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK9-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK9-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP29]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP30:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP32]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP33:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK9-SAME: () #[[ATTR0]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK9-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK9-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK9-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK9-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP35]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP36:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l65.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP38]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP39:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP41]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP42:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP44]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP45:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@main +// CHECK9-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK9-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK9-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK9-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK9-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK9: omp_offload.failed9: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK9: omp_offload.cont10: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK9-NEXT: ret i32 [[CALL]] +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP47]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP48:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP50]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP51:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP53:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn6v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56:![0-9]+]] +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK9-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then4: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP56]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK9: omp_if.else5: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK9: omp.inner.for.cond6: +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK9-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK9: omp.inner.for.body8: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK9-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK9-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK9-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK9: omp_if.then13: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK9-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK9: omp_if.else14: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_IF_END16]] +// CHECK9: omp_if.end16: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK9: omp.inner.for.inc17: +// CHECK9-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK9-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK9: omp.inner.for.end19: +// CHECK9-NEXT: br label [[OMP_IF_END20]] +// CHECK9: omp_if.end20: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK9-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK9-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK9-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK9-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK9-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK9-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK9-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK9-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK9-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK9-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK9: omp_offload.failed8: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK9: omp_offload.cont9: +// CHECK9-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK9-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK9-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK9-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK9-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK9-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK9-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK9-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK9-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK9-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK9-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK9-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK9-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK9-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK9-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK9: omp_offload.failed21: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK9: omp_offload.cont22: +// CHECK9-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP71]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP72:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP74:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn2v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP76]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP77:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP79]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP80:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK9-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP82]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP83:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP85]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP86:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK11-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes, ptr [[TMP15]], align 8 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46(i64 [[TMP1]], ptr null) #[[ATTR2:[0-9]+]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.1, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP35]], align 8 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP41]], align 4 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK11-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK11-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21:![0-9]+]], !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l46.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP25]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l54.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK11-SAME: () #[[ATTR0]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP1]], ptr [[TMP3]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP4]], align 8 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP5]], align 8 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP6]], align 8 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP10]], align 4 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP11]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP8]], ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP9]], ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.3, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP15]], align 8 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP16]], align 8 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP17]], align 8 +// CHECK11-NEXT: [[TMP18:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP18]], align 8 +// CHECK11-NEXT: [[TMP19:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP19]], align 8 +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP20]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP21]], align 4 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP22]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63(i64 [[TMP1]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP30]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP31]], align 4 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP28]], ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.5, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP35]], align 8 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP40]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP41]], align 4 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP42]], align 4 +// CHECK11-NEXT: [[TMP43:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP44:%.*]] = icmp ne i32 [[TMP43]], 0 +// CHECK11-NEXT: br i1 [[TMP44]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP0]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: store i32 [[TMP11]], ptr [[ARG_CASTED]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i64, ptr [[ARG_CASTED]], align 8, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]], i64 [[TMP12]]), !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l63.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[ARG:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: store i32 0, ptr [[ARG_ADDR]], align 4, !nontemporal [[META21]], !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l71.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@main +// CHECK11-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS5:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP7:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS8:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107(ptr null) #[[ATTR2]] +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV2]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS5]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS3]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS4]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP32:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV6:%.*]] = icmp ne i8 [[TMP32]], 0 +// CHECK11-NEXT: [[TMP33:%.*]] = select i1 [[LOADEDV6]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP34:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP33]], 0 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP31]], ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.10, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.11, ptr [[TMP40]], align 8 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP45]], align 4 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP34]], ptr [[TMP46]], align 4 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS8]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP47]], align 4 +// CHECK11-NEXT: [[TMP48:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP33]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.region_id, ptr [[KERNEL_ARGS8]]) +// CHECK11-NEXT: [[TMP49:%.*]] = icmp ne i32 [[TMP48]], 0 +// CHECK11-NEXT: br i1 [[TMP49]], label [[OMP_OFFLOAD_FAILED9:%.*]], label [[OMP_OFFLOAD_CONT10:%.*]] +// CHECK11: omp_offload.failed9: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT10]] +// CHECK11: omp_offload.cont10: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP50]]) +// CHECK11-NEXT: ret i32 [[CALL]] +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l100.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP54:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l107.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn6v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP56:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP3:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined, i64 [[TMP3]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57:![0-9]+]] +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK11-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then4: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP57]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP58:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK11: omp_if.else5: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK11: omp.inner.for.cond6: +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK11-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK11: omp.inner.for.body8: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK11-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK11-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK11-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK11: omp_if.then13: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK11-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK11: omp_if.else14: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_IF_END16]] +// CHECK11: omp_if.end16: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK11: omp.inner.for.inc17: +// CHECK11-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK11-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP60:![0-9]+]] +// CHECK11: omp.inner.for.end19: +// CHECK11-NEXT: br label [[OMP_IF_END20]] +// CHECK11: omp_if.end20: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK11-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP61]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP62:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP64:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l114.omp_outlined.omp_outlined.9 +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP65]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP66:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP68:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK11-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS2:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS3:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS4:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP6:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS7:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_10:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED14:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.12, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84(ptr null) #[[ATTR2]] +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP21:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP21]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP22:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP23]], align 8 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP22]], ptr [[TMP24]], align 8 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP25]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP26]], align 8 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS4]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS3]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP31:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV5:%.*]] = icmp ne i8 [[TMP31]], 0 +// CHECK11-NEXT: [[TMP32:%.*]] = select i1 [[LOADEDV5]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP33:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP32]], 0 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP34]], align 4 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP29]], ptr [[TMP36]], align 8 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP30]], ptr [[TMP37]], align 8 +// CHECK11-NEXT: [[TMP38:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.14, ptr [[TMP38]], align 8 +// CHECK11-NEXT: [[TMP39:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP39]], align 8 +// CHECK11-NEXT: [[TMP40:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP40]], align 8 +// CHECK11-NEXT: [[TMP41:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP41]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP44]], align 4 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP33]], ptr [[TMP45]], align 4 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS7]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP46]], align 4 +// CHECK11-NEXT: [[TMP47:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP32]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.region_id, ptr [[KERNEL_ARGS7]]) +// CHECK11-NEXT: [[TMP48:%.*]] = icmp ne i32 [[TMP47]], 0 +// CHECK11-NEXT: br i1 [[TMP48]], label [[OMP_OFFLOAD_FAILED8:%.*]], label [[OMP_OFFLOAD_CONT9:%.*]] +// CHECK11: omp_offload.failed8: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88(i64 [[TMP22]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT9]] +// CHECK11: omp_offload.cont9: +// CHECK11-NEXT: [[TMP49:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL11:%.*]] = icmp ne i32 [[TMP49]], 0 +// CHECK11-NEXT: [[STOREDV12:%.*]] = zext i1 [[TOBOOL11]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV12]], ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK11-NEXT: [[TMP50:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_10]], align 1 +// CHECK11-NEXT: [[LOADEDV13:%.*]] = icmp ne i8 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV15:%.*]] = zext i1 [[LOADEDV13]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV15]], ptr [[DOTCAPTURE_EXPR__CASTED14]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED14]], align 8 +// CHECK11-NEXT: [[TMP52:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP51]], ptr [[TMP52]], align 8 +// CHECK11-NEXT: [[TMP53:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP51]], ptr [[TMP53]], align 8 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP54]], align 8 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP55]], align 8 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP60]], align 4 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP61]], align 4 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP58]], ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP59]], ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.16, ptr [[TMP64]], align 8 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP65]], align 8 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP66]], align 8 +// CHECK11-NEXT: [[TMP67:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP67]], align 8 +// CHECK11-NEXT: [[TMP68:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP68]], align 8 +// CHECK11-NEXT: [[TMP69:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP69]], align 8 +// CHECK11-NEXT: [[TMP70:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP70]], align 4 +// CHECK11-NEXT: [[TMP71:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP71]], align 4 +// CHECK11-NEXT: [[TMP72:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP72]], align 4 +// CHECK11-NEXT: [[TMP73:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK11-NEXT: [[TMP74:%.*]] = icmp ne i32 [[TMP73]], 0 +// CHECK11-NEXT: br i1 [[TMP74]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK11: omp_offload.failed21: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92(i64 [[TMP51]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK11: omp_offload.cont22: +// CHECK11-NEXT: ret i32 0 +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP69]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP70:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l80.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP75:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l84.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn2v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP0]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined, i64 [[TMP1]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP77]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l88.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92 +// CHECK11-SAME: (i64 noundef [[DOTCAPTURE_EXPR_:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l92.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK13-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK13-SAME: () #[[ATTR0]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: store i32 0, ptr @Arg, align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@main +// CHECK13-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn6v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK13-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK13: omp_if.then: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK13: omp_if.else: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK13: omp.inner.for.cond30: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK13: omp.inner.for.body32: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK13-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK13-NEXT: call void @_Z3fn7v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK13: omp.body.continue35: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK13: omp.inner.for.inc36: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK13: omp.inner.for.end38: +// CHECK13-NEXT: br label [[OMP_IF_END]] +// CHECK13: omp_if.end: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK13-NEXT: ret i32 [[CALL]] +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK13-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn2v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK13-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK13-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK13: omp.inner.for.cond38: +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK13-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK13: omp.inner.for.body40: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK13-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK13: omp.body.continue43: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK13: omp.inner.for.inc44: +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK13-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK13: omp.inner.for.end46: +// CHECK13-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK13-NEXT: ret i32 0 +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK15-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2:![0-9]+]], !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP3:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP6]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP7:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK15-SAME: () #[[ATTR0]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: store i32 0, ptr @Arg, align 4, !nontemporal [[META2]], !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP9]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP10:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP12]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP13:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@main +// CHECK15-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP15]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn6v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP18:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK15-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK15: omp_if.then: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20:![0-9]+]] +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP20]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP21:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK15: omp_if.else: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK15: omp.inner.for.cond30: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK15: omp.inner.for.body32: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK15-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK15-NEXT: call void @_Z3fn7v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK15: omp.body.continue35: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK15: omp.inner.for.inc36: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP23:![0-9]+]] +// CHECK15: omp.inner.for.end38: +// CHECK15-NEXT: br label [[OMP_IF_END]] +// CHECK15: omp_if.end: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK15-NEXT: ret i32 [[CALL]] +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK15-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_30:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP33:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB34:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB35:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV36:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I37:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn2v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP27:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL31:%.*]] = icmp ne i32 [[TMP16]], 0 +// CHECK15-NEXT: [[STOREDV32:%.*]] = zext i1 [[TOBOOL31]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV32]], ptr [[DOTCAPTURE_EXPR_30]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB34]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB35]], align 4 +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_LB34]], align 4 +// CHECK15-NEXT: store i32 [[TMP17]], ptr [[DOTOMP_IV36]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND38:%.*]] +// CHECK15: omp.inner.for.cond38: +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31:![0-9]+]] +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_UB35]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[CMP39:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK15-NEXT: br i1 [[CMP39]], label [[OMP_INNER_FOR_BODY40:%.*]], label [[OMP_INNER_FOR_END46:%.*]] +// CHECK15: omp.inner.for.body40: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[MUL41:%.*]] = mul nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: [[ADD42:%.*]] = add nsw i32 0, [[MUL41]] +// CHECK15-NEXT: store i32 [[ADD42]], ptr [[I37]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE43:%.*]] +// CHECK15: omp.body.continue43: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC44:%.*]] +// CHECK15: omp.inner.for.inc44: +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: [[ADD45:%.*]] = add nsw i32 [[TMP21]], 1 +// CHECK15-NEXT: store i32 [[ADD45]], ptr [[DOTOMP_IV36]], align 4, !llvm.access.group [[ACC_GRP31]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND38]], !llvm.loop [[LOOP32:![0-9]+]] +// CHECK15: omp.inner.for.end46: +// CHECK15-NEXT: store i32 100, ptr [[I37]], align 4 +// CHECK15-NEXT: ret i32 0 +// diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp new file mode 100644 index 0000000000000..a612d9be52b77 --- /dev/null +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_if_openmp52_codegen.cpp @@ -0,0 +1,12190 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs --replace-value-regex "__omp_offloading_[0-9a-z]+_[0-9a-z]+" "reduction_size[.].+[.]" "pl_cond[.].+[.|,]" --prefix-filecheck-ir-name _ +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK1 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK3 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK3 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK5 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK7 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK7 + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK9 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK11 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK11 + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK13 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK15 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple aarch64-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple aarch64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK15 +// expected-no-diagnostics +#ifndef HEADER +#define HEADER + +void fn1(); +void fn2(); +void fn3(); +void fn4(); +void fn5(); +void fn6(); +void fn7(); + +int Arg; + +void gtid_test() { +#pragma omp target +#pragma omp teams distribute parallel for simd + for(int i = 0 ; i < 100; i++) {} + +#pragma omp target +#pragma omp teams distribute parallel for simd if (parallel: false) + for(int i = 0 ; i < 100; i++) { + gtid_test(); + } +} + + +void gtid_test2() { +#pragma omp target +#pragma omp teams distribute parallel for simd + for(int i = 0 ; i < 100; i++) {} + +#pragma omp target +#pragma omp teams distribute parallel for simd if (teams: false) + for(int i = 0 ; i < 100; i++) { + gtid_test2(); + } +} + + +template +int tmain(T Arg) { +#pragma omp target +#pragma omp teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + fn1(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + fn2(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (parallel: Arg) + for(int i = 0 ; i < 100; i++) { + fn3(); + } +#pragma omp target +#pragma omp teams distribute parallel for simd if (teams: Arg) + for(int i = 0 ; i < 100; i++) { + fn4(); + } + return 0; +} + +int main() { +#pragma omp target +#pragma omp teams distribute parallel for simd if (true) + for(int i = 0 ; i < 100; i++) { + + + fn5(); + } + +#pragma omp target +#pragma omp teams distribute parallel for simd if (false) + for(int i = 0 ; i < 100; i++) { + + + fn6(); + } + +#pragma omp target +#pragma omp teams distribute parallel for simd if (Arg) + for(int i = 0 ; i < 100; i++) { + + + fn7(); + } + + return tmain(Arg); +} + + + + + + +// call void [[T_OUTLINE_FUN_3:@.+]]( + + + +#endif +// CHECK1-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK1-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK1-SAME: () #[[ATTR0]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@main +// CHECK1-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK1-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK1-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK1-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK1-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK1: omp_offload.failed13: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK1: omp_offload.cont14: +// CHECK1-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK1-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK1-NEXT: ret i32 [[CALL]] +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn6v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK1-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK1-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then4: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK1: omp_if.else5: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK1: omp.inner.for.cond6: +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK1-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK1: omp.inner.for.body8: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK1-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK1-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK1-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK1-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK1: omp_if.then13: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK1-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK1: omp_if.else14: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_IF_END16]] +// CHECK1: omp_if.end16: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK1: omp.inner.for.inc17: +// CHECK1-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK1-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK1: omp.inner.for.end19: +// CHECK1-NEXT: br label [[OMP_IF_END20]] +// CHECK1: omp_if.end20: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK1-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK1-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK1: cond.true5: +// CHECK1-NEXT: br label [[COND_END7:%.*]] +// CHECK1: cond.false6: +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END7]] +// CHECK1: cond.end7: +// CHECK1-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK1-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK1: omp.inner.for.cond9: +// CHECK1-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK1-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK1: omp.inner.for.body11: +// CHECK1-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK1-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK1-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn7v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK1: omp.body.continue14: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK1: omp.inner.for.inc15: +// CHECK1-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK1-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK1: omp.inner.for.end17: +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK1-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK1-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK1-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK1-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK1-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK1-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK1-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK1-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK1-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK1-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK1-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK1-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK1-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK1-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK1-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK1-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK1-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK1-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK1-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK1-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK1: omp_offload.failed: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK1: omp_offload.cont: +// CHECK1-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK1-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK1-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK1-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK1-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK1-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK1-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK1-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK1-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK1-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK1-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK1-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK1-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK1-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK1-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK1-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK1-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK1-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK1-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK1-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK1: omp_offload.failed6: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK1: omp_offload.cont7: +// CHECK1-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK1-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK1-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK1-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK1-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK1-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK1-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK1-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK1-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK1-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK1-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK1-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK1-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK1-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK1-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK1-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK1-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK1-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK1-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK1-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK1-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK1-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK1-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK1-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK1-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK1-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK1-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK1: omp_offload.failed13: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK1: omp_offload.cont14: +// CHECK1-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK1-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK1-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK1-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK1-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK1-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK1-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK1-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK1-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK1-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK1-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK1-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK1-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK1-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK1-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK1-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK1-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK1-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK1-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK1-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK1-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK1-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK1-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK1-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK1-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK1-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK1-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK1-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK1-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK1-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK1-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK1-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK1-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK1-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK1-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK1-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK1-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK1-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK1-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK1: omp_offload.failed21: +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK1-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK1: omp_offload.cont22: +// CHECK1-NEXT: ret i32 0 +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK1-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK1-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK1-NEXT: call void @_Z3fn2v() +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK1-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK1-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK1-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK1-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK1-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK1-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK1-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK1-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK1-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK1: omp_if.then: +// CHECK1-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK1: omp_if.else: +// CHECK1-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK1-NEXT: br label [[OMP_IF_END]] +// CHECK1: omp_if.end: +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK1-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK1-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK1-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK1-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK1-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK1-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK1-NEXT: entry: +// CHECK1-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK1-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK1-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK1-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK1-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK1-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK1-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK1-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK1-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK1-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK1-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK1: cond.true: +// CHECK1-NEXT: br label [[COND_END:%.*]] +// CHECK1: cond.false: +// CHECK1-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: br label [[COND_END]] +// CHECK1: cond.end: +// CHECK1-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK1-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK1-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK1-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK1: omp.inner.for.cond: +// CHECK1-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK1-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK1-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK1: omp.inner.for.body: +// CHECK1-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK1-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK1-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK1: omp.body.continue: +// CHECK1-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK1: omp.inner.for.inc: +// CHECK1-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK1-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK1-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK1: omp.inner.for.end: +// CHECK1-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK1: omp.loop.exit: +// CHECK1-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK1-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK1-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK1-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK1: .omp.final.then: +// CHECK1-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK1-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK1: .omp.final.done: +// CHECK1-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK3-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK3-SAME: () #[[ATTR0]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@main +// CHECK3-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK3-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK3-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK3-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK3-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK3: omp_offload.failed13: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK3: omp_offload.cont14: +// CHECK3-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK3-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK3-NEXT: ret i32 [[CALL]] +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn6v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK3-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK3-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then4: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK3: omp_if.else5: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK3: omp.inner.for.cond6: +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK3-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK3: omp.inner.for.body8: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK3-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK3-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK3-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK3-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK3: omp_if.then13: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK3-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK3: omp_if.else14: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_IF_END16]] +// CHECK3: omp_if.end16: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK3: omp.inner.for.inc17: +// CHECK3-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK3-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK3: omp.inner.for.end19: +// CHECK3-NEXT: br label [[OMP_IF_END20]] +// CHECK3: omp_if.end20: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK3-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK3-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK3: cond.true5: +// CHECK3-NEXT: br label [[COND_END7:%.*]] +// CHECK3: cond.false6: +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END7]] +// CHECK3: cond.end7: +// CHECK3-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK3-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK3: omp.inner.for.cond9: +// CHECK3-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK3-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK3: omp.inner.for.body11: +// CHECK3-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK3-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK3-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn7v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK3: omp.body.continue14: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK3: omp.inner.for.inc15: +// CHECK3-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK3-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK3: omp.inner.for.end17: +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK3-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK3-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK3-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK3-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK3-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK3-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK3-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK3-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK3-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK3-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK3-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK3-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK3-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK3-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK3-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK3-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK3-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK3-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK3-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK3-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK3: omp_offload.failed: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK3: omp_offload.cont: +// CHECK3-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK3-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK3-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK3-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK3-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK3-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK3-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK3-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK3-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK3-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK3-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK3-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK3-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK3-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK3-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK3-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK3-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK3-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK3-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK3-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK3: omp_offload.failed6: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK3: omp_offload.cont7: +// CHECK3-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK3-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK3-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK3-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK3-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK3-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK3-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK3-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK3-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK3-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK3-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK3-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK3-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK3-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK3-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK3-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK3-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK3-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK3-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK3-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK3-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK3-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK3-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK3-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK3-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK3-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK3-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK3: omp_offload.failed13: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK3: omp_offload.cont14: +// CHECK3-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK3-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK3-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK3-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK3-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK3-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK3-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK3-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK3-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK3-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK3-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK3-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK3-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK3-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK3-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK3-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK3-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK3-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK3-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK3-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK3-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK3-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK3-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK3-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK3-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK3-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK3-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK3-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK3-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK3-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK3-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK3-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK3-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK3-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK3-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK3-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK3-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK3-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK3-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK3: omp_offload.failed21: +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK3-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK3: omp_offload.cont22: +// CHECK3-NEXT: ret i32 0 +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK3-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK3-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK3-NEXT: call void @_Z3fn2v() +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK3-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK3-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK3-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK3-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK3-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK3-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK3-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK3-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK3-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK3: omp_if.then: +// CHECK3-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK3: omp_if.else: +// CHECK3-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK3-NEXT: br label [[OMP_IF_END]] +// CHECK3: omp_if.end: +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK3-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK3-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK3-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK3-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK3-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK3-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK3-NEXT: entry: +// CHECK3-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK3-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK3-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK3-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK3-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK3-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK3-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK3-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK3-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK3-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK3-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK3: cond.true: +// CHECK3-NEXT: br label [[COND_END:%.*]] +// CHECK3: cond.false: +// CHECK3-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: br label [[COND_END]] +// CHECK3: cond.end: +// CHECK3-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK3-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK3-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK3-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK3: omp.inner.for.cond: +// CHECK3-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK3-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK3-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK3: omp.inner.for.body: +// CHECK3-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK3-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK3-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK3: omp.body.continue: +// CHECK3-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK3: omp.inner.for.inc: +// CHECK3-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK3-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK3-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK3: omp.inner.for.end: +// CHECK3-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK3: omp.loop.exit: +// CHECK3-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK3-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK3-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK3-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK3: .omp.final.then: +// CHECK3-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK3-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK3: .omp.final.done: +// CHECK3-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK5-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK5-SAME: () #[[ATTR0]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: ret void +// +// +// CHECK5-LABEL: define {{[^@]+}}@main +// CHECK5-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn6v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK5-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK5: omp_if.then: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK5: omp_if.else: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK5: omp.inner.for.cond30: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK5: omp.inner.for.body32: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK5-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK5-NEXT: call void @_Z3fn7v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK5: omp.body.continue35: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK5: omp.inner.for.inc36: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK5: omp.inner.for.end38: +// CHECK5-NEXT: br label [[OMP_IF_END]] +// CHECK5: omp_if.end: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK5-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK5-NEXT: ret i32 [[CALL]] +// +// +// CHECK5-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK5-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK5-NEXT: entry: +// CHECK5-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK5-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK5-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK5-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK5-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK5: omp.inner.for.cond: +// CHECK5-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK5-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK5-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK5: omp.inner.for.body: +// CHECK5-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK5-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK5-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK5: omp.body.continue: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK5: omp.inner.for.inc: +// CHECK5-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK5-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK5: omp.inner.for.end: +// CHECK5-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK5-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK5: omp.inner.for.cond7: +// CHECK5-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK5-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK5-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK5: omp.inner.for.body9: +// CHECK5-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK5-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK5-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK5-NEXT: call void @_Z3fn2v() +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK5: omp.body.continue12: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK5: omp.inner.for.inc13: +// CHECK5-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK5-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK5: omp.inner.for.end15: +// CHECK5-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK5-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK5-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK5-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK5-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK5-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK5-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK5: omp.inner.for.cond21: +// CHECK5-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK5-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK5-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK5: omp.inner.for.body23: +// CHECK5-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK5-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK5-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK5: omp.body.continue26: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK5: omp.inner.for.inc27: +// CHECK5-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK5-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK5: omp.inner.for.end29: +// CHECK5-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK5-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK5-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK5-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK5-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK5: omp.inner.for.cond35: +// CHECK5-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK5-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK5-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK5: omp.inner.for.body37: +// CHECK5-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK5-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK5-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK5: omp.body.continue40: +// CHECK5-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK5: omp.inner.for.inc41: +// CHECK5-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK5-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK5-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK5: omp.inner.for.end43: +// CHECK5-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK5-NEXT: ret i32 0 +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK7-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK7-SAME: () #[[ATTR0]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: ret void +// +// +// CHECK7-LABEL: define {{[^@]+}}@main +// CHECK7-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn6v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK7-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK7: omp_if.then: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK7: omp_if.else: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK7: omp.inner.for.cond30: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK7: omp.inner.for.body32: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK7-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK7-NEXT: call void @_Z3fn7v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK7: omp.body.continue35: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK7: omp.inner.for.inc36: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK7: omp.inner.for.end38: +// CHECK7-NEXT: br label [[OMP_IF_END]] +// CHECK7: omp_if.end: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK7-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK7-NEXT: ret i32 [[CALL]] +// +// +// CHECK7-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK7-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK7-NEXT: entry: +// CHECK7-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK7-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK7-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK7-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK7-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK7: omp.inner.for.cond: +// CHECK7-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK7-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK7-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK7: omp.inner.for.body: +// CHECK7-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK7-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK7-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK7: omp.body.continue: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK7: omp.inner.for.inc: +// CHECK7-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK7-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK7: omp.inner.for.end: +// CHECK7-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK7-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK7: omp.inner.for.cond7: +// CHECK7-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK7-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK7-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK7: omp.inner.for.body9: +// CHECK7-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK7-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK7-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK7-NEXT: call void @_Z3fn2v() +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK7: omp.body.continue12: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK7: omp.inner.for.inc13: +// CHECK7-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK7-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK7: omp.inner.for.end15: +// CHECK7-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK7-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK7-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK7-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK7-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK7-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK7-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK7: omp.inner.for.cond21: +// CHECK7-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK7-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK7-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK7: omp.inner.for.body23: +// CHECK7-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK7-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK7-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK7: omp.body.continue26: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK7: omp.inner.for.inc27: +// CHECK7-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK7-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK7: omp.inner.for.end29: +// CHECK7-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK7-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK7-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK7-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK7-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK7: omp.inner.for.cond35: +// CHECK7-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK7-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK7-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK7: omp.inner.for.body37: +// CHECK7-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK7-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK7-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK7: omp.body.continue40: +// CHECK7-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK7: omp.inner.for.inc41: +// CHECK7-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK7-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK7-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK7: omp.inner.for.end43: +// CHECK7-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK7-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK9-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK9-SAME: () #[[ATTR0]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@main +// CHECK9-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK9-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK9-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK9-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK9-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK9: omp_offload.failed13: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK9: omp_offload.cont14: +// CHECK9-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK9-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK9-NEXT: ret i32 [[CALL]] +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn6v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK9-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK9-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then4: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK9: omp_if.else5: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK9: omp.inner.for.cond6: +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK9-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK9: omp.inner.for.body8: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK9-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK9-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK9-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK9-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK9: omp_if.then13: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK9-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK9: omp_if.else14: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_IF_END16]] +// CHECK9: omp_if.end16: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK9: omp.inner.for.inc17: +// CHECK9-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK9-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK9: omp.inner.for.end19: +// CHECK9-NEXT: br label [[OMP_IF_END20]] +// CHECK9: omp_if.end20: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK9-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK9-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK9: cond.true5: +// CHECK9-NEXT: br label [[COND_END7:%.*]] +// CHECK9: cond.false6: +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END7]] +// CHECK9: cond.end7: +// CHECK9-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK9-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK9: omp.inner.for.cond9: +// CHECK9-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK9-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK9: omp.inner.for.body11: +// CHECK9-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK9-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK9-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn7v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK9: omp.body.continue14: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK9: omp.inner.for.inc15: +// CHECK9-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK9-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK9: omp.inner.for.end17: +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK9-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK9-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK9-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK9-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK9-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK9-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK9-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK9-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK9-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK9-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK9-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK9-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK9-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK9-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK9-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK9-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK9-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK9-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK9-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK9-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK9: omp_offload.failed: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK9: omp_offload.cont: +// CHECK9-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK9-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK9-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK9-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK9-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK9-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK9-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK9-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK9-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK9-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK9-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK9-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK9-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK9-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK9-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK9-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK9-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK9-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK9-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK9-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK9: omp_offload.failed6: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK9: omp_offload.cont7: +// CHECK9-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK9-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK9-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK9-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK9-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK9-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK9-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK9-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK9-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK9-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK9-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK9-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK9-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK9-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK9-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK9-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK9-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK9-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK9-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK9-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK9-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK9-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK9-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK9-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK9-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK9-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK9-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK9: omp_offload.failed13: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK9: omp_offload.cont14: +// CHECK9-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK9-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK9-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK9-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK9-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK9-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK9-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK9-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK9-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK9-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK9-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK9-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK9-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK9-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK9-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK9-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK9-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK9-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK9-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK9-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK9-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK9-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK9-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK9-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK9-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK9-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK9-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK9-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK9-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK9-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK9-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK9-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK9-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK9-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK9-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK9-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK9-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK9-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK9-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK9: omp_offload.failed21: +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK9-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK9: omp_offload.cont22: +// CHECK9-NEXT: ret i32 0 +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK9-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK9-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK9-NEXT: call void @_Z3fn2v() +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK9-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK9-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK9-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK9-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK9-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK9-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK9-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK9-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK9-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK9: omp_if.then: +// CHECK9-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK9: omp_if.else: +// CHECK9-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK9-NEXT: br label [[OMP_IF_END]] +// CHECK9: omp_if.end: +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK9-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK9-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK9-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK9-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK9-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK9-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK9-NEXT: entry: +// CHECK9-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK9-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK9-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK9-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK9-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK9-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK9-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK9-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK9-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK9-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK9-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK9: cond.true: +// CHECK9-NEXT: br label [[COND_END:%.*]] +// CHECK9: cond.false: +// CHECK9-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: br label [[COND_END]] +// CHECK9: cond.end: +// CHECK9-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK9-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK9-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK9-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK9: omp.inner.for.cond: +// CHECK9-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK9-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK9-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK9: omp.inner.for.body: +// CHECK9-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK9-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK9-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK9: omp.body.continue: +// CHECK9-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK9: omp.inner.for.inc: +// CHECK9-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK9-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK9-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK9: omp.inner.for.end: +// CHECK9-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK9: omp.loop.exit: +// CHECK9-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK9-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK9-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK9-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK9: .omp.final.then: +// CHECK9-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK9-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK9: .omp.final.done: +// CHECK9-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK11-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3:[0-9]+]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44(ptr null) #[[ATTR2:[0-9]+]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.1, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.2, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1:[0-9]+]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP24]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l44.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2:[0-9]+]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP28]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP29:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP33]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP34:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z9gtid_testv_l48.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP36]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP37:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK11-SAME: () #[[ATTR0]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.3, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.4, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.5, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.6, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP39]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP40:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l57.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP42]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP43:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP45]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP46:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z10gtid_test2v_l61.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP48]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP49:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@main +// CHECK11-SAME: () #[[ATTR3:[0-9]+]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.7, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.8, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.9, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.10, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: [[TMP40:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK11-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.12, ptr [[TMP58]], align 8 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.13, ptr [[TMP59]], align 8 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK11-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK11-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK11-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK11: omp_offload.failed13: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK11: omp_offload.cont14: +// CHECK11-NEXT: [[TMP69:%.*]] = load i32, ptr @Arg, align 4 +// CHECK11-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP69]]) +// CHECK11-NEXT: ret i32 [[CALL]] +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP51]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP52:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l95.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP54]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP55:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP57:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l103.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn6v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP59:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: [[TMP3:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV1:%.*]] = icmp ne i8 [[TMP3]], 0 +// CHECK11-NEXT: [[STOREDV2:%.*]] = zext i1 [[LOADEDV1]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV2]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP4:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined, i64 [[TMP4]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED10:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR15:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP5:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP5]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE5:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60:![0-9]+]] +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP9:%.*]] = zext i32 [[TMP8]] to i64 +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP11:%.*]] = zext i32 [[TMP10]] to i64 +// CHECK11-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[LOADEDV2:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[LOADEDV2]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP13:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[LOADEDV3:%.*]] = icmp ne i8 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV3]], label [[OMP_IF_THEN4:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then4: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined, i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP15:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined(ptr [[TMP15]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP9]], i64 [[TMP11]], i64 [[TMP13]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP16]], [[TMP17]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP60]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP61:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END20:%.*]] +// CHECK11: omp_if.else5: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6:%.*]] +// CHECK11: omp.inner.for.cond6: +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP7:%.*]] = icmp sle i32 [[TMP18]], [[TMP19]] +// CHECK11-NEXT: br i1 [[CMP7]], label [[OMP_INNER_FOR_BODY8:%.*]], label [[OMP_INNER_FOR_END19:%.*]] +// CHECK11: omp.inner.for.body8: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP21:%.*]] = zext i32 [[TMP20]] to i64 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP23:%.*]] = zext i32 [[TMP22]] to i64 +// CHECK11-NEXT: [[TMP24:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV9:%.*]] = icmp ne i8 [[TMP24]], 0 +// CHECK11-NEXT: [[STOREDV11:%.*]] = zext i1 [[LOADEDV9]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV11]], ptr [[DOTCAPTURE_EXPR__CASTED10]], align 1 +// CHECK11-NEXT: [[TMP25:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED10]], align 8 +// CHECK11-NEXT: [[TMP26:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV12:%.*]] = icmp ne i8 [[TMP26]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV12]], label [[OMP_IF_THEN13:%.*]], label [[OMP_IF_ELSE14:%.*]] +// CHECK11: omp_if.then13: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 3, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11, i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) +// CHECK11-NEXT: br label [[OMP_IF_END16:%.*]] +// CHECK11: omp_if.else14: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP27:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR15]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11(ptr [[TMP27]], ptr [[DOTBOUND_ZERO_ADDR15]], i64 [[TMP21]], i64 [[TMP23]], i64 [[TMP25]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_IF_END16]] +// CHECK11: omp_if.end16: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC17:%.*]] +// CHECK11: omp.inner.for.inc17: +// CHECK11-NEXT: [[TMP28:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP29:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD18:%.*]] = add nsw i32 [[TMP28]], [[TMP29]] +// CHECK11-NEXT: store i32 [[ADD18]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND6]], !llvm.loop [[LOOP63:![0-9]+]] +// CHECK11: omp.inner.for.end19: +// CHECK11-NEXT: br label [[OMP_IF_END20]] +// CHECK11: omp_if.end20: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP30:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP31:%.*]] = icmp ne i32 [[TMP30]], 0 +// CHECK11-NEXT: br i1 [[TMP31]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP64]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP65:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP67:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}_main_l111.omp_outlined.omp_outlined.11 +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP2]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: [[TMP3:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP4]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP5]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP6]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP7]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68:![0-9]+]] +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP8]], [[TMP9]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP11]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP68]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP69:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP13]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP4:%.*]] = icmp sgt i32 [[TMP14]], 99 +// CHECK11-NEXT: br i1 [[CMP4]], label [[COND_TRUE5:%.*]], label [[COND_FALSE6:%.*]] +// CHECK11: cond.true5: +// CHECK11-NEXT: br label [[COND_END7:%.*]] +// CHECK11: cond.false6: +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END7]] +// CHECK11: cond.end7: +// CHECK11-NEXT: [[COND8:%.*]] = phi i32 [ 99, [[COND_TRUE5]] ], [ [[TMP15]], [[COND_FALSE6]] ] +// CHECK11-NEXT: store i32 [[COND8]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9:%.*]] +// CHECK11: omp.inner.for.cond9: +// CHECK11-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP10:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK11-NEXT: br i1 [[CMP10]], label [[OMP_INNER_FOR_BODY11:%.*]], label [[OMP_INNER_FOR_END17:%.*]] +// CHECK11: omp.inner.for.body11: +// CHECK11-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL12:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK11-NEXT: [[ADD13:%.*]] = add nsw i32 0, [[MUL12]] +// CHECK11-NEXT: store i32 [[ADD13]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn7v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE14:%.*]] +// CHECK11: omp.body.continue14: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC15:%.*]] +// CHECK11: omp.inner.for.inc15: +// CHECK11-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD16:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK11-NEXT: store i32 [[ADD16]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND9]], !llvm.loop [[LOOP71:![0-9]+]] +// CHECK11: omp.inner.for.end17: +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: [[TMP21:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP22]]) +// CHECK11-NEXT: [[TMP23:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP24:%.*]] = icmp ne i32 [[TMP23]], 0 +// CHECK11-NEXT: br i1 [[TMP24]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK11-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS:%.*]], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS1:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS2:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS3:%.*]] = alloca [1 x ptr], align 8 +// CHECK11-NEXT: [[_TMP4:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS5:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS8:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS9:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS10:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[_TMP11:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS12:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: [[ARG_CASTED15:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_BASEPTRS16:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_PTRS17:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[DOTOFFLOAD_MAPPERS18:%.*]] = alloca [2 x ptr], align 8 +// CHECK11-NEXT: [[_TMP19:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[KERNEL_ARGS20:%.*]] = alloca [[STRUCT___TGT_KERNEL_ARGUMENTS]], align 8 +// CHECK11-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP0]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP1]], align 8 +// CHECK11-NEXT: [[TMP2:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP2]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP4:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP5]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP6]], align 4 +// CHECK11-NEXT: [[TMP7:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP3]], ptr [[TMP7]], align 8 +// CHECK11-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP4]], ptr [[TMP8]], align 8 +// CHECK11-NEXT: [[TMP9:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.14, ptr [[TMP9]], align 8 +// CHECK11-NEXT: [[TMP10:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.15, ptr [[TMP10]], align 8 +// CHECK11-NEXT: [[TMP11:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP11]], align 8 +// CHECK11-NEXT: [[TMP12:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP12]], align 8 +// CHECK11-NEXT: [[TMP13:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP13]], align 8 +// CHECK11-NEXT: [[TMP14:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP14]], align 8 +// CHECK11-NEXT: [[TMP15:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP15]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP16]], align 4 +// CHECK11-NEXT: [[TMP17:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP17]], align 4 +// CHECK11-NEXT: [[TMP18:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.region_id, ptr [[KERNEL_ARGS]]) +// CHECK11-NEXT: [[TMP19:%.*]] = icmp ne i32 [[TMP18]], 0 +// CHECK11-NEXT: br i1 [[TMP19]], label [[OMP_OFFLOAD_FAILED:%.*]], label [[OMP_OFFLOAD_CONT:%.*]] +// CHECK11: omp_offload.failed: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT]] +// CHECK11: omp_offload.cont: +// CHECK11-NEXT: [[TMP20:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP20]], align 8 +// CHECK11-NEXT: [[TMP21:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP21]], align 8 +// CHECK11-NEXT: [[TMP22:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_MAPPERS3]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP22]], align 8 +// CHECK11-NEXT: [[TMP23:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_BASEPTRS1]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP24:%.*]] = getelementptr inbounds [1 x ptr], ptr [[DOTOFFLOAD_PTRS2]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP25:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP25]], align 4 +// CHECK11-NEXT: [[TMP26:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 1 +// CHECK11-NEXT: store i32 1, ptr [[TMP26]], align 4 +// CHECK11-NEXT: [[TMP27:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP23]], ptr [[TMP27]], align 8 +// CHECK11-NEXT: [[TMP28:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP24]], ptr [[TMP28]], align 8 +// CHECK11-NEXT: [[TMP29:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.16, ptr [[TMP29]], align 8 +// CHECK11-NEXT: [[TMP30:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.17, ptr [[TMP30]], align 8 +// CHECK11-NEXT: [[TMP31:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP31]], align 8 +// CHECK11-NEXT: [[TMP32:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP32]], align 8 +// CHECK11-NEXT: [[TMP33:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP33]], align 8 +// CHECK11-NEXT: [[TMP34:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP34]], align 8 +// CHECK11-NEXT: [[TMP35:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP35]], align 4 +// CHECK11-NEXT: [[TMP36:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP36]], align 4 +// CHECK11-NEXT: [[TMP37:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS5]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP37]], align 4 +// CHECK11-NEXT: [[TMP38:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.region_id, ptr [[KERNEL_ARGS5]]) +// CHECK11-NEXT: [[TMP39:%.*]] = icmp ne i32 [[TMP38]], 0 +// CHECK11-NEXT: br i1 [[TMP39]], label [[OMP_OFFLOAD_FAILED6:%.*]], label [[OMP_OFFLOAD_CONT7:%.*]] +// CHECK11: omp_offload.failed6: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76(ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT7]] +// CHECK11: omp_offload.cont7: +// CHECK11-NEXT: [[TMP40:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP40]], ptr [[ARG_CASTED]], align 4 +// CHECK11-NEXT: [[TMP41:%.*]] = load i64, ptr [[ARG_CASTED]], align 8 +// CHECK11-NEXT: [[TMP42:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP42]], align 8 +// CHECK11-NEXT: [[TMP43:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP41]], ptr [[TMP43]], align 8 +// CHECK11-NEXT: [[TMP44:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP44]], align 8 +// CHECK11-NEXT: [[TMP45:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP45]], align 8 +// CHECK11-NEXT: [[TMP46:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP46]], align 8 +// CHECK11-NEXT: [[TMP47:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS10]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP47]], align 8 +// CHECK11-NEXT: [[TMP48:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS8]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP49:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS9]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP50:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP50]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP51:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP51]], 0 +// CHECK11-NEXT: [[TMP52:%.*]] = select i1 [[LOADEDV]], i32 0, i32 1 +// CHECK11-NEXT: [[TMP53:%.*]] = insertvalue [3 x i32] zeroinitializer, i32 [[TMP52]], 0 +// CHECK11-NEXT: [[TMP54:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP54]], align 4 +// CHECK11-NEXT: [[TMP55:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP55]], align 4 +// CHECK11-NEXT: [[TMP56:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP48]], ptr [[TMP56]], align 8 +// CHECK11-NEXT: [[TMP57:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP49]], ptr [[TMP57]], align 8 +// CHECK11-NEXT: [[TMP58:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.18, ptr [[TMP58]], align 8 +// CHECK11-NEXT: [[TMP59:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.19, ptr [[TMP59]], align 8 +// CHECK11-NEXT: [[TMP60:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP60]], align 8 +// CHECK11-NEXT: [[TMP61:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP61]], align 8 +// CHECK11-NEXT: [[TMP62:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP62]], align 8 +// CHECK11-NEXT: [[TMP63:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP63]], align 8 +// CHECK11-NEXT: [[TMP64:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP64]], align 4 +// CHECK11-NEXT: [[TMP65:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] [[TMP53]], ptr [[TMP65]], align 4 +// CHECK11-NEXT: [[TMP66:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS12]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP66]], align 4 +// CHECK11-NEXT: [[TMP67:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 [[TMP52]], ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.region_id, ptr [[KERNEL_ARGS12]]) +// CHECK11-NEXT: [[TMP68:%.*]] = icmp ne i32 [[TMP67]], 0 +// CHECK11-NEXT: br i1 [[TMP68]], label [[OMP_OFFLOAD_FAILED13:%.*]], label [[OMP_OFFLOAD_CONT14:%.*]] +// CHECK11: omp_offload.failed13: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81(i64 [[TMP41]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT14]] +// CHECK11: omp_offload.cont14: +// CHECK11-NEXT: [[TMP69:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: store i32 [[TMP69]], ptr [[ARG_CASTED15]], align 4 +// CHECK11-NEXT: [[TMP70:%.*]] = load i64, ptr [[ARG_CASTED15]], align 8 +// CHECK11-NEXT: [[TMP71:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP70]], ptr [[TMP71]], align 8 +// CHECK11-NEXT: [[TMP72:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: store i64 [[TMP70]], ptr [[TMP72]], align 8 +// CHECK11-NEXT: [[TMP73:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 0 +// CHECK11-NEXT: store ptr null, ptr [[TMP73]], align 8 +// CHECK11-NEXT: [[TMP74:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP74]], align 8 +// CHECK11-NEXT: [[TMP75:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP75]], align 8 +// CHECK11-NEXT: [[TMP76:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_MAPPERS18]], i64 0, i64 1 +// CHECK11-NEXT: store ptr null, ptr [[TMP76]], align 8 +// CHECK11-NEXT: [[TMP77:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_BASEPTRS16]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP78:%.*]] = getelementptr inbounds [2 x ptr], ptr [[DOTOFFLOAD_PTRS17]], i32 0, i32 0 +// CHECK11-NEXT: [[TMP79:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 0 +// CHECK11-NEXT: store i32 5, ptr [[TMP79]], align 4 +// CHECK11-NEXT: [[TMP80:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 1 +// CHECK11-NEXT: store i32 2, ptr [[TMP80]], align 4 +// CHECK11-NEXT: [[TMP81:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 2 +// CHECK11-NEXT: store ptr [[TMP77]], ptr [[TMP81]], align 8 +// CHECK11-NEXT: [[TMP82:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 3 +// CHECK11-NEXT: store ptr [[TMP78]], ptr [[TMP82]], align 8 +// CHECK11-NEXT: [[TMP83:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 4 +// CHECK11-NEXT: store ptr @.offload_sizes.20, ptr [[TMP83]], align 8 +// CHECK11-NEXT: [[TMP84:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 5 +// CHECK11-NEXT: store ptr @.offload_maptypes.21, ptr [[TMP84]], align 8 +// CHECK11-NEXT: [[TMP85:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 6 +// CHECK11-NEXT: store ptr null, ptr [[TMP85]], align 8 +// CHECK11-NEXT: [[TMP86:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 7 +// CHECK11-NEXT: store ptr null, ptr [[TMP86]], align 8 +// CHECK11-NEXT: [[TMP87:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 8 +// CHECK11-NEXT: store i64 100, ptr [[TMP87]], align 8 +// CHECK11-NEXT: [[TMP88:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 9 +// CHECK11-NEXT: store i64 0, ptr [[TMP88]], align 8 +// CHECK11-NEXT: [[TMP89:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 10 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP89]], align 4 +// CHECK11-NEXT: [[TMP90:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 11 +// CHECK11-NEXT: store [3 x i32] zeroinitializer, ptr [[TMP90]], align 4 +// CHECK11-NEXT: [[TMP91:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS20]], i32 0, i32 12 +// CHECK11-NEXT: store i32 0, ptr [[TMP91]], align 4 +// CHECK11-NEXT: [[TMP92:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB3]], i64 -1, i32 0, i32 0, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.region_id, ptr [[KERNEL_ARGS20]]) +// CHECK11-NEXT: [[TMP93:%.*]] = icmp ne i32 [[TMP92]], 0 +// CHECK11-NEXT: br i1 [[TMP93]], label [[OMP_OFFLOAD_FAILED21:%.*]], label [[OMP_OFFLOAD_CONT22:%.*]] +// CHECK11: omp_offload.failed21: +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86(i64 [[TMP70]], ptr null) #[[ATTR2]] +// CHECK11-NEXT: br label [[OMP_OFFLOAD_CONT22]] +// CHECK11: omp_offload.cont22: +// CHECK11-NEXT: ret i32 0 +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP72]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP73:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l71.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP75]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP76:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76 +// CHECK11-SAME: (ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4 +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined(ptr [[TMP11]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]) +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP12]], [[TMP13]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP78:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP14]], 0 +// CHECK11-NEXT: br i1 [[TMP15]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l76.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4 +// CHECK11-NEXT: call void @_Z3fn2v() +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP79:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__CASTED:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0 +// CHECK11-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[TMP1:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP1]], 0 +// CHECK11-NEXT: [[STOREDV1:%.*]] = zext i1 [[LOADEDV]] to i8 +// CHECK11-NEXT: store i8 [[STOREDV1]], ptr [[DOTCAPTURE_EXPR__CASTED]], align 1 +// CHECK11-NEXT: [[TMP2:%.*]] = load i64, ptr [[DOTCAPTURE_EXPR__CASTED]], align 8 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 1, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined, i64 [[TMP2]]) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTCAPTURE_EXPR_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTCAPTURE_EXPR__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTBOUND_ZERO_ADDR:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTCAPTURE_EXPR_]], ptr [[DOTCAPTURE_EXPR__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: [[TMP11:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR__ADDR]], align 1, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP12:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: store i32 0, ptr [[DOTBOUND_ZERO_ADDR]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined(ptr [[TMP12]], ptr [[DOTBOUND_ZERO_ADDR]], i64 [[TMP8]], i64 [[TMP10]]) #[[ATTR2]], !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: call void @__kmpc_end_serialized_parallel(ptr @[[GLOB3]], i32 [[TMP1]]), !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP13]], [[TMP14]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP80]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP81:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP16:%.*]] = icmp ne i32 [[TMP15]], 0 +// CHECK11-NEXT: br i1 [[TMP16]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l81.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP83]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP84:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86 +// CHECK11-SAME: (i64 noundef [[ARG:%.*]], ptr noalias noundef [[DYN_PTR:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[ARG_ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DYN_PTR_ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB3]]) +// CHECK11-NEXT: store i64 [[ARG]], ptr [[ARG_ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DYN_PTR]], ptr [[DYN_PTR_ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK11-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP1]], 0 +// CHECK11-NEXT: br i1 [[TOBOOL]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK11: omp_if.then: +// CHECK11-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK11: omp_if.else: +// CHECK11-NEXT: call void @__kmpc_push_num_teams(ptr @[[GLOB3]], i32 [[TMP0]], i32 1, i32 0) +// CHECK11-NEXT: br label [[OMP_IF_END]] +// CHECK11: omp_if.end: +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_teams(ptr @[[GLOB3]], i32 0, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined) +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_COMB_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB1]], i32 [[TMP1]], i32 92, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_COMB_LB]], ptr [[DOTOMP_COMB_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_COMB_UB]], align 4 +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP4]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86:![0-9]+]] +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]] +// CHECK11-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_COMB_LB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP8:%.*]] = zext i32 [[TMP7]] to i64 +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_COMB_UB]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP10:%.*]] = zext i32 [[TMP9]] to i64 +// CHECK11-NEXT: call void (ptr, i32, ptr, ...) @__kmpc_fork_call(ptr @[[GLOB3]], i32 2, ptr @{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined, i64 [[TMP8]], i64 [[TMP10]]), !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_STRIDE]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP11]], [[TMP12]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP86]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP87:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB1]], i32 [[TMP1]]) +// CHECK11-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 +// CHECK11-NEXT: br i1 [[TMP14]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK11-LABEL: define {{[^@]+}}@{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z5tmainIiEiT__l86.omp_outlined.omp_outlined +// CHECK11-SAME: (ptr noalias noundef [[DOTGLOBAL_TID_:%.*]], ptr noalias noundef [[DOTBOUND_TID_:%.*]], i64 noundef [[DOTPREVIOUS_LB_:%.*]], i64 noundef [[DOTPREVIOUS_UB_:%.*]]) #[[ATTR1]] { +// CHECK11-NEXT: entry: +// CHECK11-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca ptr, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_LB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTPREVIOUS_UB__ADDR:%.*]] = alloca i64, align 8 +// CHECK11-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK11-NEXT: store ptr [[DOTGLOBAL_TID_]], ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: store ptr [[DOTBOUND_TID_]], ptr [[DOTBOUND_TID__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_LB_]], ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: store i64 [[DOTPREVIOUS_UB_]], ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP0:%.*]] = load i64, ptr [[DOTPREVIOUS_LB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV:%.*]] = trunc i64 [[TMP0]] to i32 +// CHECK11-NEXT: [[TMP1:%.*]] = load i64, ptr [[DOTPREVIOUS_UB__ADDR]], align 8 +// CHECK11-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP1]] to i32 +// CHECK11-NEXT: store i32 [[CONV]], ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[CONV1]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4 +// CHECK11-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP2:%.*]] = load ptr, ptr [[DOTGLOBAL_TID__ADDR]], align 8 +// CHECK11-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4 +// CHECK11-NEXT: call void @__kmpc_for_static_init_4(ptr @[[GLOB2]], i32 [[TMP3]], i32 34, ptr [[DOTOMP_IS_LAST]], ptr [[DOTOMP_LB]], ptr [[DOTOMP_UB]], ptr [[DOTOMP_STRIDE]], i32 1, i32 1) +// CHECK11-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP4]], 99 +// CHECK11-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] +// CHECK11: cond.true: +// CHECK11-NEXT: br label [[COND_END:%.*]] +// CHECK11: cond.false: +// CHECK11-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: br label [[COND_END]] +// CHECK11: cond.end: +// CHECK11-NEXT: [[COND:%.*]] = phi i32 [ 99, [[COND_TRUE]] ], [ [[TMP5]], [[COND_FALSE]] ] +// CHECK11-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4 +// CHECK11-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK11-NEXT: store i32 [[TMP6]], ptr [[DOTOMP_IV]], align 4 +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK11: omp.inner.for.cond: +// CHECK11-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89:![0-9]+]] +// CHECK11-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[CMP2:%.*]] = icmp sle i32 [[TMP7]], [[TMP8]] +// CHECK11-NEXT: br i1 [[CMP2]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK11: omp.inner.for.body: +// CHECK11-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP9]], 1 +// CHECK11-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK11-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK11: omp.body.continue: +// CHECK11-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK11: omp.inner.for.inc: +// CHECK11-NEXT: [[TMP10:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP10]], 1 +// CHECK11-NEXT: store i32 [[ADD3]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP89]] +// CHECK11-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP90:![0-9]+]] +// CHECK11: omp.inner.for.end: +// CHECK11-NEXT: br label [[OMP_LOOP_EXIT:%.*]] +// CHECK11: omp.loop.exit: +// CHECK11-NEXT: call void @__kmpc_for_static_fini(ptr @[[GLOB2]], i32 [[TMP3]]) +// CHECK11-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_IS_LAST]], align 4 +// CHECK11-NEXT: [[TMP12:%.*]] = icmp ne i32 [[TMP11]], 0 +// CHECK11-NEXT: br i1 [[TMP12]], label [[DOTOMP_FINAL_THEN:%.*]], label [[DOTOMP_FINAL_DONE:%.*]] +// CHECK11: .omp.final.then: +// CHECK11-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK11-NEXT: br label [[DOTOMP_FINAL_DONE]] +// CHECK11: .omp.final.done: +// CHECK11-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK13-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK13-SAME: () #[[ATTR0]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: ret void +// +// +// CHECK13-LABEL: define {{[^@]+}}@main +// CHECK13-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn6v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK13-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK13: omp_if.then: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK13: omp_if.else: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK13: omp.inner.for.cond30: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK13: omp.inner.for.body32: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK13-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK13-NEXT: call void @_Z3fn7v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK13: omp.body.continue35: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK13: omp.inner.for.inc36: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK13: omp.inner.for.end38: +// CHECK13-NEXT: br label [[OMP_IF_END]] +// CHECK13: omp_if.end: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK13-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK13-NEXT: ret i32 [[CALL]] +// +// +// CHECK13-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK13-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK13-NEXT: entry: +// CHECK13-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK13-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK13-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK13-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK13-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK13: omp.inner.for.cond: +// CHECK13-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK13-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK13-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK13: omp.inner.for.body: +// CHECK13-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK13-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK13-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK13: omp.body.continue: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK13: omp.inner.for.inc: +// CHECK13-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK13-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK13: omp.inner.for.end: +// CHECK13-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK13-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK13: omp.inner.for.cond7: +// CHECK13-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK13-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK13-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK13: omp.inner.for.body9: +// CHECK13-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK13-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK13-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK13-NEXT: call void @_Z3fn2v() +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK13: omp.body.continue12: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK13: omp.inner.for.inc13: +// CHECK13-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK13-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK13: omp.inner.for.end15: +// CHECK13-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK13-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK13-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK13-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK13-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK13-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK13-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK13: omp.inner.for.cond21: +// CHECK13-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK13-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK13-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK13: omp.inner.for.body23: +// CHECK13-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK13-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK13-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK13: omp.body.continue26: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK13: omp.inner.for.inc27: +// CHECK13-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK13-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK13: omp.inner.for.end29: +// CHECK13-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK13-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK13-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK13-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK13-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK13: omp.inner.for.cond35: +// CHECK13-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK13-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK13-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK13: omp.inner.for.body37: +// CHECK13-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK13-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK13-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK13: omp.body.continue40: +// CHECK13-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK13: omp.inner.for.inc41: +// CHECK13-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK13-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK13-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK13: omp.inner.for.end43: +// CHECK13-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK13-NEXT: ret i32 0 +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z9gtid_testv +// CHECK15-SAME: () #[[ATTR0:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP1]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: call void @_Z9gtid_testv(), !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP5]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP6:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z10gtid_test2v +// CHECK15-SAME: () #[[ATTR0]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP8]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP9:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11:![0-9]+]] +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: call void @_Z10gtid_test2v(), !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4, !llvm.access.group [[ACC_GRP11]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP12:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: ret void +// +// +// CHECK15-LABEL: define {{[^@]+}}@main +// CHECK15-SAME: () #[[ATTR1:[0-9]+]] { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 0, ptr [[RETVAL]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: call void @_Z3fn5v(), !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP14]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn6v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP17:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP12:%.*]] = load i8, ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: [[LOADEDV:%.*]] = icmp ne i8 [[TMP12]], 0 +// CHECK15-NEXT: br i1 [[LOADEDV]], label [[OMP_IF_THEN:%.*]], label [[OMP_IF_ELSE:%.*]] +// CHECK15: omp_if.then: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19:![0-9]+]] +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP13]], [[TMP14]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: call void @_Z3fn7v(), !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP16]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP19]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP20:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: br label [[OMP_IF_END:%.*]] +// CHECK15: omp_if.else: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30:%.*]] +// CHECK15: omp.inner.for.cond30: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[CMP31:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP31]], label [[OMP_INNER_FOR_BODY32:%.*]], label [[OMP_INNER_FOR_END38:%.*]] +// CHECK15: omp.inner.for.body32: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[MUL33:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD34:%.*]] = add nsw i32 0, [[MUL33]] +// CHECK15-NEXT: store i32 [[ADD34]], ptr [[I20]], align 4 +// CHECK15-NEXT: call void @_Z3fn7v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE35:%.*]] +// CHECK15: omp.body.continue35: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC36:%.*]] +// CHECK15: omp.inner.for.inc36: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: [[ADD37:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD37]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND30]], !llvm.loop [[LOOP22:![0-9]+]] +// CHECK15: omp.inner.for.end38: +// CHECK15-NEXT: br label [[OMP_IF_END]] +// CHECK15: omp_if.end: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: [[TMP21:%.*]] = load i32, ptr @Arg, align 4 +// CHECK15-NEXT: [[CALL:%.*]] = call noundef i32 @_Z5tmainIiEiT_(i32 noundef [[TMP21]]) +// CHECK15-NEXT: ret i32 [[CALL]] +// +// +// CHECK15-LABEL: define {{[^@]+}}@_Z5tmainIiEiT_ +// CHECK15-SAME: (i32 noundef [[ARG:%.*]]) #[[ATTR0]] comdat { +// CHECK15-NEXT: entry: +// CHECK15-NEXT: [[ARG_ADDR:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[TMP:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP2:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB3:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB4:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV5:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I6:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTCAPTURE_EXPR_:%.*]] = alloca i8, align 1 +// CHECK15-NEXT: [[_TMP16:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB17:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB18:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV19:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I20:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[_TMP30:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_LB31:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_UB32:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[DOTOMP_IV33:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: [[I34:%.*]] = alloca i32, align 4 +// CHECK15-NEXT: store i32 [[ARG]], ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB]], align 4 +// CHECK15-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTOMP_LB]], align 4 +// CHECK15-NEXT: store i32 [[TMP0]], ptr [[DOTOMP_IV]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND:%.*]] +// CHECK15: omp.inner.for.cond: +// CHECK15-NEXT: [[TMP1:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23:![0-9]+]] +// CHECK15-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]] +// CHECK15-NEXT: br i1 [[CMP]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]] +// CHECK15: omp.inner.for.body: +// CHECK15-NEXT: [[TMP3:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP3]], 1 +// CHECK15-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]] +// CHECK15-NEXT: store i32 [[ADD]], ptr [[I]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: call void @_Z3fn1v(), !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE:%.*]] +// CHECK15: omp.body.continue: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC:%.*]] +// CHECK15: omp.inner.for.inc: +// CHECK15-NEXT: [[TMP4:%.*]] = load i32, ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: [[ADD1:%.*]] = add nsw i32 [[TMP4]], 1 +// CHECK15-NEXT: store i32 [[ADD1]], ptr [[DOTOMP_IV]], align 4, !llvm.access.group [[ACC_GRP23]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]] +// CHECK15: omp.inner.for.end: +// CHECK15-NEXT: store i32 100, ptr [[I]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[TMP5:%.*]] = load i32, ptr [[DOTOMP_LB3]], align 4 +// CHECK15-NEXT: store i32 [[TMP5]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7:%.*]] +// CHECK15: omp.inner.for.cond7: +// CHECK15-NEXT: [[TMP6:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[TMP7:%.*]] = load i32, ptr [[DOTOMP_UB4]], align 4 +// CHECK15-NEXT: [[CMP8:%.*]] = icmp sle i32 [[TMP6]], [[TMP7]] +// CHECK15-NEXT: br i1 [[CMP8]], label [[OMP_INNER_FOR_BODY9:%.*]], label [[OMP_INNER_FOR_END15:%.*]] +// CHECK15: omp.inner.for.body9: +// CHECK15-NEXT: [[TMP8:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[MUL10:%.*]] = mul nsw i32 [[TMP8]], 1 +// CHECK15-NEXT: [[ADD11:%.*]] = add nsw i32 0, [[MUL10]] +// CHECK15-NEXT: store i32 [[ADD11]], ptr [[I6]], align 4 +// CHECK15-NEXT: call void @_Z3fn2v() +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE12:%.*]] +// CHECK15: omp.body.continue12: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC13:%.*]] +// CHECK15: omp.inner.for.inc13: +// CHECK15-NEXT: [[TMP9:%.*]] = load i32, ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: [[ADD14:%.*]] = add nsw i32 [[TMP9]], 1 +// CHECK15-NEXT: store i32 [[ADD14]], ptr [[DOTOMP_IV5]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND7]], !llvm.loop [[LOOP26:![0-9]+]] +// CHECK15: omp.inner.for.end15: +// CHECK15-NEXT: store i32 100, ptr [[I6]], align 4 +// CHECK15-NEXT: [[TMP10:%.*]] = load i32, ptr [[ARG_ADDR]], align 4 +// CHECK15-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP10]], 0 +// CHECK15-NEXT: [[STOREDV:%.*]] = zext i1 [[TOBOOL]] to i8 +// CHECK15-NEXT: store i8 [[STOREDV]], ptr [[DOTCAPTURE_EXPR_]], align 1 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB18]], align 4 +// CHECK15-NEXT: [[TMP11:%.*]] = load i32, ptr [[DOTOMP_LB17]], align 4 +// CHECK15-NEXT: store i32 [[TMP11]], ptr [[DOTOMP_IV19]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21:%.*]] +// CHECK15: omp.inner.for.cond21: +// CHECK15-NEXT: [[TMP12:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27:![0-9]+]] +// CHECK15-NEXT: [[TMP13:%.*]] = load i32, ptr [[DOTOMP_UB18]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[CMP22:%.*]] = icmp sle i32 [[TMP12]], [[TMP13]] +// CHECK15-NEXT: br i1 [[CMP22]], label [[OMP_INNER_FOR_BODY23:%.*]], label [[OMP_INNER_FOR_END29:%.*]] +// CHECK15: omp.inner.for.body23: +// CHECK15-NEXT: [[TMP14:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[MUL24:%.*]] = mul nsw i32 [[TMP14]], 1 +// CHECK15-NEXT: [[ADD25:%.*]] = add nsw i32 0, [[MUL24]] +// CHECK15-NEXT: store i32 [[ADD25]], ptr [[I20]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: call void @_Z3fn3v(), !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE26:%.*]] +// CHECK15: omp.body.continue26: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC27:%.*]] +// CHECK15: omp.inner.for.inc27: +// CHECK15-NEXT: [[TMP15:%.*]] = load i32, ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: [[ADD28:%.*]] = add nsw i32 [[TMP15]], 1 +// CHECK15-NEXT: store i32 [[ADD28]], ptr [[DOTOMP_IV19]], align 4, !llvm.access.group [[ACC_GRP27]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND21]], !llvm.loop [[LOOP28:![0-9]+]] +// CHECK15: omp.inner.for.end29: +// CHECK15-NEXT: store i32 100, ptr [[I20]], align 4 +// CHECK15-NEXT: store i32 0, ptr [[DOTOMP_LB31]], align 4 +// CHECK15-NEXT: store i32 99, ptr [[DOTOMP_UB32]], align 4 +// CHECK15-NEXT: [[TMP16:%.*]] = load i32, ptr [[DOTOMP_LB31]], align 4 +// CHECK15-NEXT: store i32 [[TMP16]], ptr [[DOTOMP_IV33]], align 4 +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND35:%.*]] +// CHECK15: omp.inner.for.cond35: +// CHECK15-NEXT: [[TMP17:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30:![0-9]+]] +// CHECK15-NEXT: [[TMP18:%.*]] = load i32, ptr [[DOTOMP_UB32]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[CMP36:%.*]] = icmp sle i32 [[TMP17]], [[TMP18]] +// CHECK15-NEXT: br i1 [[CMP36]], label [[OMP_INNER_FOR_BODY37:%.*]], label [[OMP_INNER_FOR_END43:%.*]] +// CHECK15: omp.inner.for.body37: +// CHECK15-NEXT: [[TMP19:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[MUL38:%.*]] = mul nsw i32 [[TMP19]], 1 +// CHECK15-NEXT: [[ADD39:%.*]] = add nsw i32 0, [[MUL38]] +// CHECK15-NEXT: store i32 [[ADD39]], ptr [[I34]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: call void @_Z3fn4v(), !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: br label [[OMP_BODY_CONTINUE40:%.*]] +// CHECK15: omp.body.continue40: +// CHECK15-NEXT: br label [[OMP_INNER_FOR_INC41:%.*]] +// CHECK15: omp.inner.for.inc41: +// CHECK15-NEXT: [[TMP20:%.*]] = load i32, ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: [[ADD42:%.*]] = add nsw i32 [[TMP20]], 1 +// CHECK15-NEXT: store i32 [[ADD42]], ptr [[DOTOMP_IV33]], align 4, !llvm.access.group [[ACC_GRP30]] +// CHECK15-NEXT: br label [[OMP_INNER_FOR_COND35]], !llvm.loop [[LOOP31:![0-9]+]] +// CHECK15: omp.inner.for.end43: +// CHECK15-NEXT: store i32 100, ptr [[I34]], align 4 +// CHECK15-NEXT: ret i32 0 +// From 9a4ad0acce7abf452746a5eab7c85730031152a3 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 10 Jul 2026 10:46:26 +0200 Subject: [PATCH 097/125] [libc] Assorted improvements to [gs]etitimer (#206974) This started out as a patch adding a syscall wrapper for the two functions. It still does that, but along the way I (or rather AI) discovered an edge case in the truncation of microsecond values, where we could turn bogus values into seemingly valid ones by throwing away the high-order bits. Additionally, when writing a test case, I noticed that the (64-bit) kernel returns EINVAL for these out-or-range values. Our check returns EOVERFLOW in this case, so I also change our error code in order to provide an uniform behavior for the test case. Neither of these (the check and the EINVAL error code) are present in glibc (which lets truncated usec values through and returns EOVERFLOW on second truncation), but I think it's better to be consistent with the 64-bit behavior. The EOVERFLOW error also has no foundation in POSIX whereas EINVAL is mentioned as an error for invalid microseconds. While in there, I also define ITIMER_REAL, ITIMER_VIRTUAL, and ITIMER_PROF in linux/sys-time-macros.h and update code to use them instead of raw numbers. Assisted by Gemini. --- libc/hdr/CMakeLists.txt | 9 ++ libc/hdr/sys_time_macros.h | 27 ++++++ .../llvm-libc-macros/linux/sys-time-macros.h | 5 ++ libc/include/sys/time.yaml | 6 ++ .../linux/syscall_wrappers/CMakeLists.txt | 43 ++++++++++ .../OSUtil/linux/syscall_wrappers/alarm.h | 49 +++++++++++ .../OSUtil/linux/syscall_wrappers/getitimer.h | 55 +++++++++++++ .../OSUtil/linux/syscall_wrappers/setitimer.h | 82 +++++++++++++++++++ libc/src/sys/time/linux/CMakeLists.txt | 6 +- libc/src/sys/time/linux/getitimer.cpp | 31 ++----- libc/src/sys/time/linux/setitimer.cpp | 53 ++---------- libc/src/unistd/linux/CMakeLists.txt | 4 +- libc/src/unistd/linux/alarm.cpp | 43 ++-------- libc/test/src/sys/time/CMakeLists.txt | 2 + libc/test/src/sys/time/getitimer_test.cpp | 3 +- libc/test/src/sys/time/setitimer_test.cpp | 29 ++++++- 16 files changed, 327 insertions(+), 120 deletions(-) create mode 100644 libc/hdr/sys_time_macros.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 3558019e50608..5ad356f89d913 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -231,6 +231,15 @@ add_proxy_header_library( libc.include.llvm-libc-macros.sys_ptrace_macros ) +add_proxy_header_library( + sys_time_macros + HDRS + sys_time_macros.h + FULL_BUILD_DEPENDS + libc.include.sys_time + libc.include.llvm-libc-macros.sys_time_macros +) + add_header_library(unistd_overlay HDRS unistd_overlay.h) add_proxy_header_library( unistd_macros diff --git a/libc/hdr/sys_time_macros.h b/libc/hdr/sys_time_macros.h new file mode 100644 index 0000000000000..94fb829783b64 --- /dev/null +++ b/libc/hdr/sys_time_macros.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Proxy header for sys/time.h macros. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_HDR_SYS_TIME_MACROS_H +#define LLVM_LIBC_HDR_SYS_TIME_MACROS_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/sys-time-macros.h" + +#else // Overlay mode + +#include + +#endif // LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_SYS_TIME_MACROS_H diff --git a/libc/include/llvm-libc-macros/linux/sys-time-macros.h b/libc/include/llvm-libc-macros/linux/sys-time-macros.h index e97819594adcb..677eab50ba098 100644 --- a/libc/include/llvm-libc-macros/linux/sys-time-macros.h +++ b/libc/include/llvm-libc-macros/linux/sys-time-macros.h @@ -9,6 +9,11 @@ #ifndef LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H #define LLVM_LIBC_MACROS_LINUX_SYS_TIME_MACROS_H +// Timer types for setitimer(2). +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + // Add two timevals and put the result in timeval_ptr_result. If the resulting // usec value is greater than 999,999 then the microseconds are turned into full // seconds (1,000,000 is subtracted from usec and 1 is added to sec). diff --git a/libc/include/sys/time.yaml b/libc/include/sys/time.yaml index f1dcdff354652..5869646a003cd 100644 --- a/libc/include/sys/time.yaml +++ b/libc/include/sys/time.yaml @@ -2,6 +2,12 @@ header: sys/time.h standards: - posix macros: + - macro_name: ITIMER_REAL + macro_header: sys-time-macros.h + - macro_name: ITIMER_VIRTUAL + macro_header: sys-time-macros.h + - macro_name: ITIMER_PROF + macro_header: sys-time-macros.h - macro_name: timeradd macro_header: sys-time-macros.h types: diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt index a3cdb17e9ea5c..27df4c3f22afb 100644 --- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt @@ -1,3 +1,18 @@ +add_header_library( + alarm + HDRS + alarm.h + DEPENDS + libc.hdr.sys_time_macros + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + add_header_library( getrandom HDRS @@ -245,6 +260,34 @@ add_header_library( libc.include.sys_syscall ) +add_header_library( + getitimer + HDRS + getitimer.h + DEPENDS + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + +add_header_library( + setitimer + HDRS + setitimer.h + DEPENDS + libc.hdr.errno_macros + libc.hdr.types.struct_itimerval + libc.include.sys_syscall + libc.src.__support.CPP.limits + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config +) + add_header_library( setsockopt HDRS diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h new file mode 100644 index 0000000000000..754b1d273acba --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/alarm.h @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for alarm. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H + +#include "hdr/sys_time_macros.h" +#include "hdr/types/struct_itimerval.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h" +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr alarm(unsigned int seconds) { +#ifdef SYS_alarm + return syscall_checked(SYS_alarm, seconds); +#elif defined(SYS_setitimer) + struct itimerval old_itv; + struct itimerval itv = {}; + itv.it_value.tv_sec = seconds; + ErrorOr ret = linux_syscalls::setitimer(ITIMER_REAL, &itv, &old_itv); + if (!ret) + return Error(ret.error()); + return static_cast(old_itv.it_value.tv_sec + + (old_itv.it_value.tv_usec > 0 ? 1 : 0)); +#else +#error "alarm implementation not available for this architecture" +#endif +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_ALARM_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h new file mode 100644 index 0000000000000..86211700ac688 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/getitimer.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for getitimer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H + +#include "hdr/types/struct_itimerval.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr getitimer(int which, struct itimerval *curr_val) { + if constexpr (sizeof(time_t) == sizeof(long)) { + return syscall_checked(SYS_getitimer, which, curr_val); + } else { + // There is no SYS_getitimer_time64 call, so we can't use time_t directly, + // and need to convert from long first. + long curr_val32[4]; + long *curr_val32_ptr = curr_val ? curr_val32 : nullptr; + + ErrorOr ret = + syscall_checked(SYS_getitimer, which, curr_val32_ptr); + + if (!ret) + return ret; + + if (curr_val) { + curr_val->it_interval.tv_sec = curr_val32[0]; + curr_val->it_interval.tv_usec = curr_val32[1]; + curr_val->it_value.tv_sec = curr_val32[2]; + curr_val->it_value.tv_usec = curr_val32[3]; + } + return ret; + } +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_GETITIMER_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h new file mode 100644 index 0000000000000..82cb1d84b8d81 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/setitimer.h @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Syscall wrapper for setitimer. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H + +#include "hdr/errno_macros.h" +#include "hdr/types/struct_itimerval.h" +#include "src/__support/CPP/limits.h" +#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr setitimer(int which, const struct itimerval *new_val, + struct itimerval *old_val) { + if constexpr (sizeof(time_t) == sizeof(long)) { + return syscall_checked(SYS_setitimer, which, new_val, old_val); + } else { + // There is no SYS_setitimer_time64 call, so we can't use time_t directly, + // and need to convert it to long first. + long old_val32[4]; + long *old_val32_ptr = old_val ? old_val32 : nullptr; + long new_val32[4]; + long *new_val32_ptr = nullptr; + + if (new_val) { + // Check for overflow before casting to 32-bit long. We'll let the kernel + // do the final validation. We're just making sure the truncation does not + // change the value. + auto fits_long = [](auto val) { + return val <= cpp::numeric_limits::max() && + val >= cpp::numeric_limits::min(); + }; + if (!fits_long(new_val->it_interval.tv_sec) || + !fits_long(new_val->it_value.tv_sec) || + !fits_long(new_val->it_interval.tv_usec) || + !fits_long(new_val->it_value.tv_usec)) { + return Error(EINVAL); + } + + new_val32[0] = static_cast(new_val->it_interval.tv_sec); + new_val32[1] = static_cast(new_val->it_interval.tv_usec); + new_val32[2] = static_cast(new_val->it_value.tv_sec); + new_val32[3] = static_cast(new_val->it_value.tv_usec); + new_val32_ptr = new_val32; + } + + ErrorOr ret = syscall_checked(SYS_setitimer, which, new_val32_ptr, + old_val32_ptr); + + if (!ret) + return ret; + + if (old_val) { + old_val->it_interval.tv_sec = old_val32[0]; + old_val->it_interval.tv_usec = old_val32[1]; + old_val->it_value.tv_sec = old_val32[2]; + old_val->it_value.tv_usec = old_val32[3]; + } + return ret; + } +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SETITIMER_H diff --git a/libc/src/sys/time/linux/CMakeLists.txt b/libc/src/sys/time/linux/CMakeLists.txt index 60fbd14f73174..e74269d721c56 100644 --- a/libc/src/sys/time/linux/CMakeLists.txt +++ b/libc/src/sys/time/linux/CMakeLists.txt @@ -24,9 +24,10 @@ add_entrypoint_object( ../setitimer.h DEPENDS libc.hdr.types.struct_itimerval - libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.setitimer libc.src.__support.OSUtil.osutil libc.src.__support.common + libc.src.__support.macros.config libc.src.errno.errno ) @@ -38,8 +39,9 @@ add_entrypoint_object( ../getitimer.h DEPENDS libc.hdr.types.struct_itimerval - libc.include.sys_syscall + libc.src.__support.OSUtil.linux.syscall_wrappers.getitimer libc.src.__support.OSUtil.osutil libc.src.__support.common + libc.src.__support.macros.config libc.src.errno.errno ) diff --git a/libc/src/sys/time/linux/getitimer.cpp b/libc/src/sys/time/linux/getitimer.cpp index 2a40491bc95fb..f875bc9b13b7e 100644 --- a/libc/src/sys/time/linux/getitimer.cpp +++ b/libc/src/sys/time/linux/getitimer.cpp @@ -7,38 +7,17 @@ //===----------------------------------------------------------------------===// #include "src/sys/time/getitimer.h" -#include "hdr/types/struct_itimerval.h" -#include "src/__support/OSUtil/syscall.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/getitimer.h" #include "src/__support/common.h" #include "src/__support/libc_errno.h" -#include +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, getitimer, (int which, struct itimerval *curr_value)) { - long ret = 0; - if constexpr (sizeof(time_t) > sizeof(long)) { - // There is no SYS_getitimer_time64 call, so we can't use time_t directly. - if (curr_value) { - long curr_value32[4]; - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, - curr_value32); - if (!ret) { - curr_value->it_interval.tv_sec = curr_value32[0]; - curr_value->it_interval.tv_usec = curr_value32[1]; - curr_value->it_value.tv_sec = curr_value32[2]; - curr_value->it_value.tv_usec = curr_value32[3]; - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, nullptr); - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_getitimer, which, curr_value); - } - - // On failure, return -1 and set errno. - if (ret < 0) { - libc_errno = static_cast(-ret); + ErrorOr ret = linux_syscalls::getitimer(which, curr_value); + if (!ret) { + libc_errno = ret.error(); return -1; } return 0; diff --git a/libc/src/sys/time/linux/setitimer.cpp b/libc/src/sys/time/linux/setitimer.cpp index 2c2f0d7198204..07cb9180a7f7e 100644 --- a/libc/src/sys/time/linux/setitimer.cpp +++ b/libc/src/sys/time/linux/setitimer.cpp @@ -6,62 +6,19 @@ // //===----------------------------------------------------------------------===// #include "src/sys/time/setitimer.h" -#include "hdr/errno_macros.h" -#include "hdr/types/struct_itimerval.h" -#include "src/__support/CPP/limits.h" -#include "src/__support/OSUtil/syscall.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/setitimer.h" #include "src/__support/common.h" #include "src/__support/libc_errno.h" -#include +#include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, setitimer, (int which, const struct itimerval *new_value, struct itimerval *old_value)) { - long ret = 0; - if constexpr (sizeof(time_t) > sizeof(long)) { - // There is no SYS_setitimer_time64 call, so we can't use time_t directly, - // and need to convert it to long first. - long old_value32[4]; - long *old_value32_ptr = old_value ? old_value32 : nullptr; - - if (new_value) { - // Check for overflow before casting to 32-bit long. - if (new_value->it_interval.tv_sec > cpp::numeric_limits::max() || - new_value->it_interval.tv_sec < cpp::numeric_limits::min() || - new_value->it_value.tv_sec > cpp::numeric_limits::max() || - new_value->it_value.tv_sec < cpp::numeric_limits::min()) { - libc_errno = EOVERFLOW; - return -1; - } - - long new_value32[4] = {static_cast(new_value->it_interval.tv_sec), - static_cast(new_value->it_interval.tv_usec), - static_cast(new_value->it_value.tv_sec), - static_cast(new_value->it_value.tv_usec)}; - - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, - new_value32, old_value32_ptr); - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, nullptr, - old_value32_ptr); - } - - if (!ret && old_value) { - old_value->it_interval.tv_sec = old_value32[0]; - old_value->it_interval.tv_usec = old_value32[1]; - old_value->it_value.tv_sec = old_value32[2]; - old_value->it_value.tv_usec = old_value32[3]; - } - } else { - ret = LIBC_NAMESPACE::syscall_impl(SYS_setitimer, which, new_value, - old_value); - } - - // On failure, return -1 and set errno. - if (ret < 0) { - libc_errno = static_cast(-ret); + ErrorOr ret = linux_syscalls::setitimer(which, new_value, old_value); + if (!ret) { + libc_errno = ret.error(); return -1; } return 0; diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt index af385e9bbed72..168b61bede853 100644 --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -5,9 +5,7 @@ add_entrypoint_object( HDRS ../alarm.h DEPENDS - libc.hdr.types.struct_itimerval - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.src.__support.OSUtil.linux.syscall_wrappers.alarm libc.src.__support.common libc.src.__support.macros.config ) diff --git a/libc/src/unistd/linux/alarm.cpp b/libc/src/unistd/linux/alarm.cpp index f849e487a3f96..bc2febff0248f 100644 --- a/libc/src/unistd/linux/alarm.cpp +++ b/libc/src/unistd/linux/alarm.cpp @@ -12,50 +12,17 @@ //===----------------------------------------------------------------------===// #include "src/unistd/alarm.h" - -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/alarm.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include // For syscall numbers. - -#ifndef SYS_alarm -#include "hdr/types/struct_itimerval.h" -#endif - namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(unsigned int, alarm, (unsigned int seconds)) { -#ifdef SYS_alarm - return static_cast( - LIBC_NAMESPACE::syscall_impl(SYS_alarm, seconds)); -#elif defined(SYS_setitimer) - // On 32-bit architectures with 64-bit time_t, SYS_setitimer still expects - // 32-bit fields. We must convert itimerval to use 32-bit fields. - if constexpr (sizeof(time_t) > sizeof(long)) { - long itv32[4] = {0, 0, static_cast(seconds), 0}; - long old_itv32[4]; - long ret = LIBC_NAMESPACE::syscall_impl( - SYS_setitimer, 0 /* ITIMER_REAL */, itv32, old_itv32); - if (ret < 0) - return 0; - return static_cast(old_itv32[2] + (old_itv32[3] > 0 ? 1 : 0)); - } else { - struct itimerval itv, old_itv; - itv.it_interval.tv_sec = 0; - itv.it_interval.tv_usec = 0; - itv.it_value.tv_sec = seconds; - itv.it_value.tv_usec = 0; - long ret = LIBC_NAMESPACE::syscall_impl( - SYS_setitimer, 0 /* ITIMER_REAL */, &itv, &old_itv); - if (ret < 0) - return 0; - return static_cast(old_itv.it_value.tv_sec + - (old_itv.it_value.tv_usec > 0 ? 1 : 0)); - } -#else -#error "alarm implementation not available for this architecture" -#endif + ErrorOr ret = linux_syscalls::alarm(seconds); + if (!ret) + return 0; + return ret.value(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/sys/time/CMakeLists.txt b/libc/test/src/sys/time/CMakeLists.txt index 2468b4ae2cc34..eb9753bb5bf2d 100644 --- a/libc/test/src/sys/time/CMakeLists.txt +++ b/libc/test/src/sys/time/CMakeLists.txt @@ -27,6 +27,7 @@ add_libc_unittest( SRCS setitimer_test.cpp DEPENDS + libc.hdr.sys_time_macros libc.include.signal libc.src.sys.time.setitimer libc.src.signal.sigaction @@ -44,6 +45,7 @@ add_libc_unittest( SRCS getitimer_test.cpp DEPENDS + libc.hdr.sys_time_macros libc.src.sys.time.getitimer libc.src.__support.common libc.src.errno.errno diff --git a/libc/test/src/sys/time/getitimer_test.cpp b/libc/test/src/sys/time/getitimer_test.cpp index c1d6f72701627..93d885760a5af 100644 --- a/libc/test/src/sys/time/getitimer_test.cpp +++ b/libc/test/src/sys/time/getitimer_test.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/sys_time_macros.h" #include "hdr/types/struct_itimerval.h" #include "src/sys/time/getitimer.h" #include "test/UnitTest/ErrnoCheckingTest.h" @@ -23,7 +24,7 @@ TEST_F(LlvmLibcSysTimeGetitimerTest, SmokeTest) { timer.it_interval.tv_sec = -1; timer.it_interval.tv_usec = -1; - ASSERT_THAT(LIBC_NAMESPACE::getitimer(0, &timer), + ASSERT_THAT(LIBC_NAMESPACE::getitimer(ITIMER_REAL, &timer), returns(EQ(0)).with_errno(EQ(0))); ASSERT_TRUE(timer.it_value.tv_sec == 0); diff --git a/libc/test/src/sys/time/setitimer_test.cpp b/libc/test/src/sys/time/setitimer_test.cpp index 115f9e662ed46..aa4feb6aace4d 100644 --- a/libc/test/src/sys/time/setitimer_test.cpp +++ b/libc/test/src/sys/time/setitimer_test.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "hdr/sys_time_macros.h" #include "hdr/types/struct_itimerval.h" #include "hdr/types/struct_sigaction.h" #include "src/signal/sigaction.h" @@ -37,7 +38,7 @@ TEST_F(LlvmLibcSysTimeSetitimerTest, SmokeTest) { timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; // One-shot timer - ASSERT_THAT(LIBC_NAMESPACE::setitimer(0, &timer, nullptr), + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), returns(EQ(0)).with_errno(EQ(0))); while (true) { @@ -49,9 +50,33 @@ TEST_F(LlvmLibcSysTimeSetitimerTest, SmokeTest) { } TEST_F(LlvmLibcSysTimeSetitimerTest, InvalidRetTest) { - struct itimerval timer; + struct itimerval timer = {}; // out of range timer type (which) ASSERT_THAT(LIBC_NAMESPACE::setitimer(99, &timer, nullptr), returns(NE(0)).with_errno(NE(0))); + + // invalid microseconds (>= 1000000) + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 1000000; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + // negative microseconds + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = -1; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + // Test 64-bit microsecond values that would truncate to a valid 32-bit value + // (< 1000000). 0x100000047, If truncated to 32-bit integer, becomes 0x47. + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0x1'0000'0047; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); + + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0xffff'ffff'0000'0047; + ASSERT_THAT(LIBC_NAMESPACE::setitimer(ITIMER_REAL, &timer, nullptr), + returns(EQ(-1)).with_errno(EQ(EINVAL))); } From 83950f4c84d0b59d539f5819d67167d896eaa6a5 Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Fri, 10 Jul 2026 09:56:22 +0100 Subject: [PATCH 098/125] [lldb-dap] Log the adapter's stdio during cleanup (#208432) The adapter may crash for any reason especially if it is built with sanitizers. Log the adapter's stdout and stderr. --- .../lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py | 7 +++++++ .../packages/Python/lldbsuite/test/tools/lldb_dap/utils.py | 1 + 2 files changed, 8 insertions(+) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py index 2b2412bcea072..ac74770e2e4bc 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/lldb_dap_testcase.py @@ -153,6 +153,13 @@ def create_debug_adapter( def cleanup_adapter(): if adapter.is_alive: adapter.kill() + # The debug adapter may have a reason the test failed. + if stderr := adapter.process.stderr: + if err_str := stderr.read().decode(): + self.logger.debug("The adapter stderr: \n%s", err_str) + if stdout := adapter.process.stdout: + if err_str := stdout.read().decode(): + self.logger.debug("The adapter stdout: \n%s", err_str) self.addTearDownHook(cleanup_adapter) return adapter diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py index db89d9f77ceba..61147e3e31e52 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/utils.py @@ -156,6 +156,7 @@ def kill(self): self._process.wait(timeout=2.0) except subprocess.TimeoutExpired: self._process.kill() + self._process.wait() def _read_listening_uri(self) -> str: # lldb-dap will print the listening address once the listener is From 06e7dfcb3e64b2a4f13affeea5098860bedbd5bb Mon Sep 17 00:00:00 2001 From: Ebuka Ezike Date: Fri, 10 Jul 2026 09:57:08 +0100 Subject: [PATCH 099/125] [lldb-dap] Migrate all DAP module tests. (#207869) migrate tests module, moduleEvents and moduleSymbols --- .../module-event/TestDAP_module_event.py | 69 ++++----- .../tools/lldb-dap/module/TestDAP_module.py | 145 ++++++++++-------- .../moduleSymbols/TestDAP_moduleSymbols.py | 34 ++-- 3 files changed, 127 insertions(+), 121 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py index bf64f7f822ea2..63eb0e70a2f50 100644 --- a/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py +++ b/lldb/test/API/tools/lldb-dap/module-event/TestDAP_module_event.py @@ -1,57 +1,56 @@ -import dap_server -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil -import lldbdap_testcase -import re +from lldbsuite.test.decorators import ( + skipIfTargetDoesNotSupportSharedLibraries, + skipIfWindows, +) +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, StoppedReason +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase @skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_module_event(DAPTestCaseBase): @skipIfWindows def test_module_event(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" - breakpoint1_line = line_number(source, "// breakpoint 1") - breakpoint2_line = line_number(source, "// breakpoint 2") - breakpoint3_line = line_number(source, "// breakpoint 3") - - breakpoint_ids = self.set_source_breakpoints( - source, [breakpoint1_line, breakpoint2_line, breakpoint3_line] + bp1_line = line_number(source, "// breakpoint 1") + bp2_line = line_number(source, "// breakpoint 2") + bp3_line = line_number(source, "// breakpoint 3") + + with session.configure(LaunchArgs(program=program)) as ctx: + [bp1, bp2, bp3] = session.resolve_source_breakpoints( + source, [bp1_line, bp2_line, bp3_line] + ) + # Wait for the breakpoint before dlopen. + before_dlopen_event = session.verify_stopped_on_breakpoint( + bp1, after=ctx.process_event ) - self.continue_to_breakpoints(breakpoint_ids) - - # We're now stopped at breakpoint 1 before the dlopen. Flush all the module events. - self.dap_server.wait_for_module_events() # Continue to the second breakpoint, before the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp2) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - module_name = event["body"]["module"]["name"] - module_id = event["body"]["module"]["id"] - self.assertEqual(event["body"]["reason"], "new") - self.assertIn("libother", module_name) + new_module_event = session.verify_next_module_event(after=before_dlopen_event) + module_id = new_module_event.body.module.id + self.assertEqual(new_module_event.body.reason, "new") + self.assertIn("libother", new_module_event.body.module.name) # Continue to the third breakpoint, after the dlclose. - self.continue_to_breakpoints(breakpoint_ids) + session.continue_to_breakpoint(bp3) # Make sure we got a module event for libother. - event = self.dap_server.wait_for_event(["module"]) - self.assertIsNotNone(event, "didn't get a module event") - reason = event["body"]["reason"] + removed_module_event = session.verify_next_module_event(after=new_module_event) + reason = removed_module_event.body.reason self.assertEqual(reason, "removed") - self.assertEqual(event["body"]["module"]["id"], module_id) + self.assertEqual(removed_module_event.body.module.id, module_id) # The removed module event should omit everything but the module id and name # as they are required fields. - module_data = event["body"]["module"] - required_keys = ["id", "name"] - self.assertListEqual(list(module_data.keys()), required_keys) - self.assertEqual(module_data["name"], "", "expects empty name.") + removed_module = removed_module_event.body.module + self.assertIsNotNone(removed_module.id) + self.assertIsNotNone(removed_module.name) + self.assertEqual(removed_module.name, "", "expects empty name.") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py index 629427a4e138d..ce7a2b8dc8b1f 100644 --- a/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py +++ b/lldb/test/API/tools/lldb-dap/module/TestDAP_module.py @@ -2,88 +2,95 @@ Test lldb-dap module request """ -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -import lldbdap_testcase +import platform import re +from lldbsuite.test.decorators import skipIfWindows, skipUnlessDarwin +from lldbsuite.test.lldbtest import line_number +from lldbsuite.test.tools.lldb_dap.dap_types import ( + CompileUnitsArgs, + LaunchArgs, + ModuleEvent, + ModuleReason, +) +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -@skipIfTargetDoesNotSupportSharedLibraries() -class TestDAP_module(lldbdap_testcase.DAPTestCaseBase): - def run_test(self, symbol_basename, expect_debug_info_size): + +class TestDAP_module(DAPTestCaseBase): + def run_test(self, symbol_basename: str, expect_debug_info_size: bool): + session = self.build_and_create_session() program_basename = "a.out.stripped" program = self.getBuildArtifact(program_basename) - self.build_and_launch(program) - functions = ["foo"] - # This breakpoint will be resolved only when the libfoo module is loaded - breakpoint_ids = self.set_function_breakpoints( - functions, wait_for_resolve=False - ) - self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint") - self.continue_to_breakpoints(breakpoint_ids) - active_modules = self.dap_server.get_modules() + with session.configure(LaunchArgs(program)) as ctx: + # This breakpoint will be resolved only when the libfoo module is loaded. + breakpoints = session.set_function_breakpoints(["foo"]).body.breakpoints + self.assertEqual(len(breakpoints), 1, "expect one breakpoint.") + foo_bp_id = self.expect_not_none(breakpoints[0].id) + self.assertFalse(breakpoints[0].verified) + + session.verify_stopped_on_breakpoint(foo_bp_id, after=ctx.process_event) + active_modules = session.get_modules() program_module = active_modules[program_basename] self.assertIn( program_basename, active_modules, - "%s module is in active modules" % (program_basename), + f"{program_basename} module is in active modules", ) - self.assertIn("name", program_module, "make sure name is in module") - self.assertEqual(program_basename, program_module["name"]) - self.assertIn("path", program_module, "make sure path is in module") - self.assertEqual(program, program_module["path"]) - self.assertNotIn( - "symbolFilePath", - program_module, - "Make sure a.out.stripped has no debug info", + self.assertEqual(program_basename, program_module.name) + self.assertIsNotNone(program_module.path, "make sure path is in module") + self.assertEqual(program, program_module.path) + self.assertIsNone( + program_module.symbolFilePath, "Make sure a.out.stripped has no debug info" ) symbols_path = self.getBuildArtifact(symbol_basename) - self.dap_server.request_evaluate( - "`%s" % ('target symbols add -s "%s" "%s"' % (program, symbols_path)), - context="repl", + event_before_mod_change = session.last_event() + session.evaluate( + f'''`target symbols add -s "{program}" "{symbols_path}"''', context="repl" ) - def check_symbols_loaded_with_size(): - active_modules = self.dap_server.get_modules() - program_module = active_modules[program_basename] - self.assertIn("symbolFilePath", program_module) - self.assertIn(symbols_path, program_module["symbolFilePath"]) - size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") - return size_regex.match(program_module["debugInfoSize"]) + # Make sure we got an update event for the program module when the + # symbols got added. + changed_event = session.verify_next_module_event( + ModuleReason.CHANGED, after=event_before_mod_change + ) + changed_module = changed_event.body.module + self.assertEqual(program_module.name, changed_module.name) + self.assertIsNotNone(changed_module.symbolFilePath) + changed_symbols_path = self.expect_not_none(changed_module.symbolFilePath) + self.assertIn(symbols_path, changed_symbols_path) if expect_debug_info_size: - self.assertTrue( - self.wait_until(check_symbols_loaded_with_size), - "expect has debug info size", + changed_debug_size = self.expect_not_none(changed_module.debugInfoSize) + size_regex = re.compile(r"[0-9]+(\.[0-9]*)?[KMG]?B") + self.assertRegex( + changed_debug_size, size_regex, "expect has debug info size" ) - active_modules = self.dap_server.get_modules() + active_modules = session.get_modules() program_module = active_modules[program_basename] - self.assertEqual(program_basename, program_module["name"]) - self.assertEqual(program, program_module["path"]) - self.assertIn("addressRange", program_module) - - # Collect all the module names we saw as events. - module_new_names = [] - module_changed_names = [] - for module_event in self.dap_server.wait_for_module_events(): - reason = module_event["body"]["reason"] - if reason == "new": - module_new_names.append(module_event["body"]["module"]["name"]) - elif reason == "changed": - module_changed_names.append(module_event["body"]["module"]["name"]) + self.assertEqual(program_basename, program_module.name) + self.assertEqual(program, program_module.path) + self.assertIsNotNone(program_module.addressRange) + + # Collect all the modules added before we changed the program module. + new_module_names = [] + + def seen_module_changed_event(event: ModuleEvent): + if event.body.reason == ModuleReason.NEW: + new_module_names.append(event.body.module.name) + + return event.seq == changed_event.seq + + init_resp = ctx.init_response + session.wait_for_module_event(after=init_resp, until=seen_module_changed_event) # Make sure we got an event for every active module. - self.assertNotEqual(len(module_new_names), 0) + self.assertNotEqual(len(new_module_names), 0) for module in active_modules: - self.assertIn(module, module_new_names) + self.assertIn(module, new_module_names) - # Make sure we got an update event for the program module when the - # symbols got added. - self.assertNotEqual(len(module_changed_names), 0) - self.assertIn(program_module["name"], module_changed_names) - self.continue_to_exit() + session.continue_to_exit() @skipIfWindows def test_modules(self): @@ -112,18 +119,20 @@ def test_modules_dsym(self): @skipIfWindows def test_compile_units(self): + session = self.build_and_create_session() program = self.getBuildArtifact("a.out") - self.build_and_launch(program) source = "main.cpp" main_source_path = self.getSourcePath(source) - breakpoint1_line = line_number(source, "// breakpoint 1") - lines = [breakpoint1_line] - breakpoint_ids = self.set_source_breakpoints(source, lines) - self.continue_to_breakpoints(breakpoint_ids) - moduleId = self.dap_server.get_modules()["a.out"]["id"] - response = self.dap_server.request_compileUnits(moduleId) - self.assertTrue(response["body"]) - cu_paths = [cu["compileUnitPath"] for cu in response["body"]["compileUnits"]] + with session.configure(LaunchArgs(program)) as ctx: + breakpoint1_line = line_number(source, "// breakpoint 1") + bp_ids = session.resolve_source_breakpoints(source, [breakpoint1_line]) + process_event = ctx.process_event + + session.verify_stopped_on_breakpoint(bp_ids, after=process_event) + + module_id = session.get_modules()["a.out"].id + response = session.send_request(CompileUnitsArgs(module_id)).result() + cu_paths = [cu.compileUnitPath for cu in response.body.compileUnits] self.assertIn(main_source_path, cu_paths, "Real path to main.cpp matches") - self.continue_to_exit() + session.continue_to_exit() diff --git a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py index 2336b9f2a5a1a..5a1edeb679bc5 100644 --- a/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py +++ b/lldb/test/API/tools/lldb-dap/moduleSymbols/TestDAP_moduleSymbols.py @@ -2,11 +2,12 @@ Test lldb-dap moduleSymbols request """ -import lldbdap_testcase -from lldbsuite.test.decorators import * +from lldbsuite.test.decorators import skipIfWindows +from lldbsuite.test.tools.lldb_dap.dap_types import LaunchArgs, ModuleSymbolsArgs +from lldbsuite.test.tools.lldb_dap.lldb_dap_testcase import DAPTestCaseBase -class TestDAP_moduleSymbols(lldbdap_testcase.DAPTestCaseBase): +class TestDAP_moduleSymbols(DAPTestCaseBase): # On windows LLDB doesn't recognize symbols in a.out. @skipIfWindows def test_moduleSymbols(self): @@ -14,27 +15,24 @@ def test_moduleSymbols(self): Test that the moduleSymbols request returns correct symbols from the module. """ program = self.getBuildArtifact("a.out") - self.build_and_launch(program) + session = self.build_and_create_session() + session.launch(LaunchArgs(program=program)) - symbol_names = [] - i = 0 + symbol_names = set() + start = 0 + page_size = 100 while True: - next_symbol = self.dap_server.request_moduleSymbols( - moduleName="a.out", startIndex=i, count=1 + module_sym_args = ModuleSymbolsArgs( + moduleName="a.out", startIndex=start, count=page_size ) - self.assertIn("symbols", next_symbol["body"]) - result_symbols = next_symbol["body"]["symbols"] - self.assertLessEqual(len(result_symbols), 1) - if len(result_symbols) == 0: - break + response = session.send_request(module_sym_args).result() + symbols = response.body.symbols + symbol_names.update(sym.name for sym in symbols) - self.assertIn("name", result_symbols[0]) - symbol_names.append(result_symbols[0]["name"]) - i += 1 - if i >= 1000: + if len(symbols) < page_size: break + start += page_size - self.assertGreater(len(symbol_names), 0) self.assertIn("main", symbol_names) self.assertIn("func1", symbol_names) self.assertIn("func2", symbol_names) From 5eb8007046bc3e7f7ca7befc4cd097bb66525044 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 10 Jul 2026 10:58:58 +0200 Subject: [PATCH 100/125] Revert "Reapply "runtimes: Pass CMAKE_SYSTEM_NAME based on target triple" (#205133) (#205522)" (#208644) The change broke the runtimes build for Android; see discussion on the PR. There are fixes in progress, but let's revert to unbreak the tree until all those are ready to land. This reverts commit 00b2f81418233397e601afaeea6d62c47a6c368a and the follow-up commit 1008b485e4807476c831910cf404a0315f06c788. --- clang/cmake/modules/ClangConfig.cmake.in | 5 +- cmake/Modules/GetTripleCMakeSystemName.cmake | 89 ------------------- cmake/Modules/NormalizeTriple.cmake | 36 -------- llvm/cmake/modules/LLVMConfig.cmake.in | 67 +++++++------- .../modules/LLVMExternalProjectUtils.cmake | 64 ++++--------- llvm/runtimes/CMakeLists.txt | 4 + runtimes/CMakeLists.txt | 18 +++- 7 files changed, 72 insertions(+), 211 deletions(-) delete mode 100644 cmake/Modules/GetTripleCMakeSystemName.cmake delete mode 100644 cmake/Modules/NormalizeTriple.cmake diff --git a/clang/cmake/modules/ClangConfig.cmake.in b/clang/cmake/modules/ClangConfig.cmake.in index e199c7e17b6b7..68f723d050117 100644 --- a/clang/cmake/modules/ClangConfig.cmake.in +++ b/clang/cmake/modules/ClangConfig.cmake.in @@ -13,10 +13,7 @@ set(CLANG_LINK_CLANG_DYLIB "@CLANG_LINK_CLANG_DYLIB@") set(CLANG_DEFAULT_LINKER "@CLANG_DEFAULT_LINKER@") # Provide all our library targets to users. -# Skip when cross-compiling, as host library targets are not usable. -if(NOT CMAKE_CROSSCOMPILING) - @CLANG_CONFIG_INCLUDE_EXPORTS@ -endif() +@CLANG_CONFIG_INCLUDE_EXPORTS@ # By creating clang-tablegen-targets here, subprojects that depend on Clang's # tablegen-generated headers can always depend on this target whether building diff --git a/cmake/Modules/GetTripleCMakeSystemName.cmake b/cmake/Modules/GetTripleCMakeSystemName.cmake deleted file mode 100644 index 6cd8d3c59324e..0000000000000 --- a/cmake/Modules/GetTripleCMakeSystemName.cmake +++ /dev/null @@ -1,89 +0,0 @@ -#===--------------------------------------------------------------------===// -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for details. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -#===--------------------------------------------------------------------===// - -# Extract the OS component from a target triple and map it to the -# corresponding CMake system name. -# -# Usage: -# get_triple_cmake_system_name( ) -# -# Parses the triple (arch-vendor-os[-env]) and sets to the -# CMake-style system name (e.g. "Darwin", "Linux", "Windows"). -# Unrecognized OS values are mapped to "Generic". This expects a -# normalized triple. - -function(get_triple_cmake_system_name triple out_var) - string(REPLACE "-" ";" _components "${triple}") - list(LENGTH _components _len) - if(_len LESS 3) - set(${out_var} "${CMAKE_HOST_SYSTEM_NAME}" PARENT_SCOPE) - return() - endif() - - list(GET _components 1 _vendor) - list(GET _components 2 _os) - set(_env "") - if(_len GREATER_EQUAL 4) - list(GET _components 3 _env) - endif() - - # Check the special environment components first, since it can - # override the usual OS mapping. - if("${_env}" MATCHES "^android") - set(${out_var} "Android" PARENT_SCOPE) - elseif("${_env}" MATCHES "^cygnus") - set(${out_var} "CYGWIN" PARENT_SCOPE) - elseif("${_os}" MATCHES "^darwin|^macos") - set(${out_var} "Darwin" PARENT_SCOPE) - elseif("${_os}" MATCHES "^ios") - set(${out_var} "iOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^tvos") - set(${out_var} "tvOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^watchos") - set(${out_var} "watchOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^xros|^visionos") - set(${out_var} "visionOS" PARENT_SCOPE) - elseif("${_vendor}" STREQUAL "apple") - # Catch-all for other Apple triples (e.g. driverkit, bridgeos). - set(${out_var} "Darwin" PARENT_SCOPE) - elseif("${_os}" MATCHES "^linux") - set(${out_var} "Linux" PARENT_SCOPE) - elseif("${_os}" MATCHES "^windows") - set(${out_var} "Windows" PARENT_SCOPE) - elseif("${_os}" MATCHES "^freebsd|^kfreebsd") - set(${out_var} "FreeBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^netbsd") - set(${out_var} "NetBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^openbsd") - set(${out_var} "OpenBSD" PARENT_SCOPE) - elseif("${_os}" MATCHES "^dragonfly") - set(${out_var} "DragonFly" PARENT_SCOPE) - elseif("${_os}" MATCHES "^solaris") - set(${out_var} "SunOS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^aix") - set(${out_var} "AIX" PARENT_SCOPE) - elseif("${_os}" MATCHES "^fuchsia") - set(${out_var} "Fuchsia" PARENT_SCOPE) - elseif("${_os}" MATCHES "^haiku") - set(${out_var} "Haiku" PARENT_SCOPE) - elseif("${_os}" MATCHES "^emscripten") - set(${out_var} "Emscripten" PARENT_SCOPE) - elseif("${_os}" MATCHES "^wasi") - set(${out_var} "WASI" PARENT_SCOPE) - elseif("${_os}" MATCHES "^rtems") - set(${out_var} "RTEMS" PARENT_SCOPE) - elseif("${_os}" MATCHES "^zos") - set(${out_var} "OS390" PARENT_SCOPE) - elseif("${_os}" MATCHES "^hurd") - set(${out_var} "GNU" PARENT_SCOPE) - elseif("${_os}" MATCHES "^serenity") - set(${out_var} "SerenityOS" PARENT_SCOPE) - else() - set(${out_var} "Generic" PARENT_SCOPE) - endif() -endfunction() diff --git a/cmake/Modules/NormalizeTriple.cmake b/cmake/Modules/NormalizeTriple.cmake deleted file mode 100644 index 08f09a22bdbb0..0000000000000 --- a/cmake/Modules/NormalizeTriple.cmake +++ /dev/null @@ -1,36 +0,0 @@ -#===--------------------------------------------------------------------===// -# -# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -# See https://llvm.org/LICENSE.txt for details. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# -#===--------------------------------------------------------------------===// - -# Normalize a target triple using clang's -print-target-triple. -# -# Usage: -# normalize_triple( ) -# -# Runs --target= -print-target-triple to produce a -# canonical triple. If the compiler invocation fails (e.g. the compiler -# is not clang), is returned unchanged. - -function(normalize_triple compiler triple out_var) - set(_prefix "") - if(CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC") - set(_prefix "/clang:") - endif() - execute_process( - COMMAND "${compiler}" "${_prefix}--target=${triple}" "${_prefix}-print-target-triple" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET) - if(_result EQUAL 0 AND _output) - set(${out_var} "${_output}" PARENT_SCOPE) - else() - # TODO(#97876): Report an error. - message(WARNING "Failed to execute `${compiler} ${_prefix}--target=${triple} ${_prefix}-print-target-triple` to normalize target triple.") - set(${out_var} "${triple}" PARENT_SCOPE) - endif() -endfunction() diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in index 8eaf659d82c0c..300c25e7c6101 100644 --- a/llvm/cmake/modules/LLVMConfig.cmake.in +++ b/llvm/cmake/modules/LLVMConfig.cmake.in @@ -56,47 +56,52 @@ set(LLVM_ENABLE_ASSERTIONS @LLVM_ENABLE_ASSERTIONS@) set(LLVM_ENABLE_EH @LLVM_ENABLE_EH@) set(LLVM_ENABLE_FFI @LLVM_ENABLE_FFI@) +if(LLVM_ENABLE_FFI) + find_package(FFI) +endif() + set(LLVM_ENABLE_RTTI @LLVM_ENABLE_RTTI@) + +set(LLVM_ENABLE_LIBEDIT @HAVE_LIBEDIT@) +if(LLVM_ENABLE_LIBEDIT) + find_package(LibEdit) +endif() + set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@) + set(LLVM_ENABLE_UNWIND_TABLES @LLVM_ENABLE_UNWIND_TABLES@) + set(LLVM_ENABLE_ZLIB @LLVM_ENABLE_ZLIB@) +if(LLVM_ENABLE_ZLIB) + set(ZLIB_ROOT @ZLIB_ROOT@) + find_package(ZLIB) +endif() + set(LLVM_ENABLE_ZSTD @LLVM_ENABLE_ZSTD@) +if(LLVM_ENABLE_ZSTD) + find_package(zstd) +endif() + set(LLVM_ENABLE_LIBXML2 @LLVM_ENABLE_LIBXML2@) +if(LLVM_ENABLE_LIBXML2) + find_package(LibXml2) +endif() + set(LLVM_ENABLE_CURL @LLVM_ENABLE_CURL@) +if(LLVM_ENABLE_CURL) + find_package(CURL) +endif() + set(LLVM_ENABLE_HTTPLIB @LLVM_ENABLE_HTTPLIB@) +if(LLVM_ENABLE_HTTPLIB) + find_package(httplib) +endif() + set(LLVM_WITH_Z3 @LLVM_WITH_Z3@) -set(LLVM_ENABLE_DIA_SDK @LLVM_ENABLE_DIA_SDK@) -set(LLVM_ENABLE_LIBEDIT @HAVE_LIBEDIT@) -# These are host libraries that LLVM was built with. Only find them when the -# consumer can actually use them (i.e. not when cross-compiling for an -# incompatible target). -if(NOT CMAKE_CROSSCOMPILING) - if(LLVM_ENABLE_FFI) - find_package(FFI) - endif() - if(LLVM_ENABLE_LIBEDIT) - find_package(LibEdit) - endif() - if(LLVM_ENABLE_ZLIB) - set(ZLIB_ROOT @ZLIB_ROOT@) - find_package(ZLIB) - endif() - if(LLVM_ENABLE_ZSTD) - find_package(zstd) - endif() - if(LLVM_ENABLE_LIBXML2) - find_package(LibXml2) - endif() - if(LLVM_ENABLE_CURL) - find_package(CURL) - endif() - if(LLVM_ENABLE_HTTPLIB) - find_package(httplib) - endif() - if(LLVM_ENABLE_DIA_SDK) - find_package(DIASDK) - endif() +set(LLVM_ENABLE_DIA_SDK @LLVM_ENABLE_DIA_SDK@) +if(LLVM_ENABLE_DIA_SDK) + find_package(DIASDK) endif() set(LLVM_NATIVE_ARCH @LLVM_NATIVE_ARCH@) diff --git a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake index 9567792e664e4..ee270d70a778d 100644 --- a/llvm/cmake/modules/LLVMExternalProjectUtils.cmake +++ b/llvm/cmake/modules/LLVMExternalProjectUtils.cmake @@ -84,6 +84,12 @@ function(llvm_ExternalProject_Add name source_dir) endif() endforeach() + # If CMAKE_SYSTEM_NAME is not set explicitly in the arguments passed to us, + # reflect CMake's own default. + if (NOT _cmake_system_name) + set(_cmake_system_name "${CMAKE_HOST_SYSTEM_NAME}") + endif() + if(NOT ARG_TARGET_TRIPLE) set(target_triple ${LLVM_DEFAULT_TARGET_TRIPLE}) else() @@ -92,36 +98,6 @@ function(llvm_ExternalProject_Add name source_dir) is_msvc_triple(is_msvc_target "${target_triple}") - if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING) - set(_cmake_c_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_cxx_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_asm_compiler "${_cmake_c_compiler}") - if(is_msvc_target) - set(_cmake_c_compiler "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}") - set(_cmake_cxx_compiler "${_cmake_c_compiler}") - set(_cmake_asm_compiler "${_cmake_c_compiler}") - endif() - else() - set(_cmake_c_compiler "${CMAKE_C_COMPILER}") - set(_cmake_cxx_compiler "${CMAKE_CXX_COMPILER}") - set(_cmake_asm_compiler "${CMAKE_C_COMPILER}") - endif() - - # If CMAKE_SYSTEM_NAME is not set explicitly in the arguments passed to us, - # derive it from the target triple if available, otherwise reflect CMake's - # own default. This ensures that cross-compilation targets get the correct - # platform files (e.g. AMDGPU targets on a Darwin host won't get macOS flags). - if (NOT _cmake_system_name) - if(ARG_TARGET_TRIPLE) - include(NormalizeTriple) - normalize_triple("${_cmake_c_compiler}" "${ARG_TARGET_TRIPLE}" _normalized_triple) - include(GetTripleCMakeSystemName) - get_triple_cmake_system_name("${_normalized_triple}" _cmake_system_name) - else() - set(_cmake_system_name "${CMAKE_HOST_SYSTEM_NAME}") - endif() - endif() - if(NOT ARG_TOOLCHAIN_TOOLS) set(ARG_TOOLCHAIN_TOOLS clang) if (ARG_ENABLE_FORTRAN) @@ -255,9 +231,15 @@ function(llvm_ExternalProject_Add name source_dir) if(ARG_USE_TOOLCHAIN AND NOT CMAKE_CROSSCOMPILING) if(CLANG_IN_TOOLCHAIN) - set(compiler_args -DCMAKE_C_COMPILER=${_cmake_c_compiler} - -DCMAKE_CXX_COMPILER=${_cmake_cxx_compiler} - -DCMAKE_ASM_COMPILER=${_cmake_asm_compiler}) + if(is_msvc_target) + set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}) + else() + set(compiler_args -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}) + endif() endif() if(FLANG_IN_TOOLCHAIN) list(APPEND compiler_args -DCMAKE_Fortran_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/flang${CMAKE_EXECUTABLE_SUFFIX}) @@ -397,22 +379,6 @@ function(llvm_ExternalProject_Add name source_dir) list(APPEND compiler_args -DCMAKE_CXX_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) list(APPEND compiler_args -DCMAKE_Fortran_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) list(APPEND compiler_args -DCMAKE_ASM_COMPILER_TARGET=${ARG_TARGET_TRIPLE}) - - # Pass CMAKE_SYSTEM_NAME derived from the target triple so the sub-build - # loads the correct platform files instead of the host's. - if(NOT "${_cmake_system_name}" STREQUAL "${CMAKE_HOST_SYSTEM_NAME}") - list(APPEND compiler_args -DCMAKE_SYSTEM_NAME=${_cmake_system_name}) - endif() - - # Forward Darwin-specific variables only when targeting Darwin. - if("${_cmake_system_name}" STREQUAL "Darwin") - if(CMAKE_OSX_SYSROOT) - list(APPEND compiler_args -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}) - endif() - if(CMAKE_OSX_DEPLOYMENT_TARGET) - list(APPEND compiler_args -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}) - endif() - endif() endif() if(CMAKE_VERBOSE_MAKEFILE) diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index 22f57a3688fc4..3cc98fdbd257d 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -4,6 +4,10 @@ # the two files. set(COMMON_CMAKE_ARGS "-DHAVE_LLVM_LIT=ON;-DCLANG_RESOURCE_DIR=${CLANG_RESOURCE_DIR};-DLLVM_LIBDIR_SUFFIX=${LLVM_LIBDIR_SUFFIX}") +if(APPLE AND CMAKE_OSX_SYSROOT AND (LLVM_TARGET_TRIPLE STREQUAL LLVM_HOST_TRIPLE)) + # Only propagate the host sysroot for native runtimes builds. + list(APPEND RUNTIMES_CMAKE_ARGS "-DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT}") +endif() foreach(proj ${LLVM_ENABLE_RUNTIMES}) string(TOUPPER "${proj}" canon_name) STRING(REGEX REPLACE "-" "_" canon_name ${canon_name}) diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index 95da13caf68b1..67ed49a7dcabb 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -235,8 +235,22 @@ message(STATUS "LLVM default target triple: ${LLVM_DEFAULT_TARGET_TRIPLE}") set(LLVM_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}") if(CMAKE_C_COMPILER_ID MATCHES "Clang") - include(NormalizeTriple) - normalize_triple("${CMAKE_C_COMPILER}" "${LLVM_DEFAULT_TARGET_TRIPLE}" LLVM_DEFAULT_TARGET_TRIPLE) + set(option_prefix "") + if (CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC") + set(option_prefix "/clang:") + endif() + set(print_target_triple ${CMAKE_C_COMPILER} ${option_prefix}--target=${LLVM_DEFAULT_TARGET_TRIPLE} ${option_prefix}-print-target-triple) + execute_process(COMMAND ${print_target_triple} + RESULT_VARIABLE result + OUTPUT_VARIABLE output + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(result EQUAL 0) + set(LLVM_DEFAULT_TARGET_TRIPLE ${output}) + else() + string(REPLACE ";" " " print_target_triple "${print_target_triple}") + # TODO(#97876): Report an error. + message(WARNING "Failed to execute `${print_target_triple}` to normalize target triple.") + endif() endif() # Determine output and install paths based on LLVM_TARGET_TRIPLE From 810a463e9d0c011c738f544be3507cda9f85f8ad Mon Sep 17 00:00:00 2001 From: jeanPerier Date: Fri, 10 Jul 2026 11:00:56 +0200 Subject: [PATCH 101/125] [flang][openacc] make openacc-use-reduction-combine cl switch default (#208473) Turn the switch on now that is has been tested. Will remove the switch in a later patch. --- .../Support/FIROpenACCTypeInterfaces.cpp | 2 +- .../Lower/OpenACC/acc-reduction-maxmin.f90 | 16 +- flang/test/Lower/OpenACC/acc-reduction.f90 | 214 ++---------------- 3 files changed, 30 insertions(+), 202 deletions(-) diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp index e18fc5f2782ad..e0f0450ec119c 100644 --- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp +++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp @@ -39,7 +39,7 @@ static llvm::cl::opt useAccReductionCombine( "openacc-use-reduction-combine", llvm::cl::desc("Whether to generate acc.reduction_combine. Does not " "control reduction for MIN/MAX and logical reductions."), - llvm::cl::init(false)); + llvm::cl::init(true)); static llvm::cl::opt useAccReductionCombineAll( "openacc-use-reduction-combine-all", diff --git a/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 b/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 index cd6e3fd2fb07b..bac76bb1dd202 100644 --- a/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction-maxmin.f90 @@ -58,40 +58,40 @@ end subroutine acc_array_reduction_min ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_minimumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMUM: } combiner { ! EXTREMUM: fir.do_loop -! EXTREMUM: %[[MINIMUMF_0:.*]] = arith.minimumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_minimumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMUM: %[[CST:.*]] = arith.constant 3.40282347E+38 : f32 ! EXTREMUM: } combiner { -! EXTREMUM: %[[MINIMUMF_0:.*]] = arith.minimumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_maximumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMUM: } combiner { ! EXTREMUM: fir.do_loop -! EXTREMUM: %[[MAXIMUMF_0:.*]] = arith.maximumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMUM-LABEL: acc.reduction.recipe @reduction_maximumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMUM-LABEL: } combiner { -! EXTREMUM: %[[MAXIMUMF_0:.*]] = arith.maximumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_minnumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMENUM: } combiner { ! EXTREMENUM: fir.do_loop -! EXTREMENUM: %[[MINNUMF_0:.*]] = arith.minnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_minnumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMENUM: %[[CST:.*]] = arith.constant 3.40282347E+38 : f32 ! EXTREMENUM: } combiner { -! EXTREMENUM: %[[MINNUMF_0:.*]] = arith.minnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_maxnumf_ref_10xf32 : !fir.ref> reduction_operator init { ! EXTREMENUM: } combiner { ! EXTREMENUM: fir.do_loop -! EXTREMENUM: %[[MAXNUMF_0:.*]] = arith.maxnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! EXTREMENUM-LABEL: acc.reduction.recipe @reduction_maxnumf_ref_f32 : !fir.ref reduction_operator init { ! EXTREMENUM-LABEL: } combiner { -! EXTREMENUM: %[[MAXNUMF_0:.*]] = arith.maxnumf %{{.*}}, %{{.*}} fastmath : f32 +! EXTREMENUM: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref ! PORTABLE-NANNSZ-LABEL: acc.reduction.recipe @reduction_min_ref_10xf32 : !fir.ref> reduction_operator init { ! PORTABLE-NANNSZ: } combiner { diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 index aa79a3789a009..fce9d0e2ff54d 100644 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -1,7 +1,6 @@ ! This test checks lowering of OpenACC reduction clause. ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s -! RUN: bbc -fopenacc -emit-hlfir %s -o - -openacc-use-reduction-combine | FileCheck -check-prefix=ACC_COMBINE %s ! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_box_heap_l32 : !fir.ref>>> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): @@ -320,10 +319,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_9]] to %[[CONSTANT_5]] step %[[CONSTANT_9]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_4:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_4]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.box> ! CHECK: } @@ -438,10 +434,7 @@ ! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index ! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_1]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.box> @@ -523,10 +516,7 @@ ! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_17]] to %[[CONSTANT_6]] step %[[CONSTANT_17]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> @@ -583,10 +573,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_5]] step %[[CONSTANT_10]] unordered { ! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -609,10 +596,7 @@ ! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.ptr ! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> ! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.ptr -! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr -! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.ptr -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.ptr +! CHECK: acc.reduction_combine %[[BOX_ADDR_0]] into %[[BOX_ADDR_1]] : !fir.ptr ! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> ! CHECK-LABEL: } destroy { @@ -642,10 +626,7 @@ ! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap ! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> ! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.heap -! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap -! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.heap -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.heap +! CHECK: acc.reduction_combine %[[BOX_ADDR_0]] into %[[BOX_ADDR_1]] : !fir.heap ! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> ! CHECK-LABEL: } destroy { @@ -669,10 +650,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> -! CHECK: %[[MULC_0:.*]] = fir.mulc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex -! CHECK: hlfir.assign %[[MULC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref> ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -689,10 +667,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> -! CHECK: %[[ADDC_0:.*]] = fir.addc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex -! CHECK: hlfir.assign %[[ADDC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref> ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -769,10 +744,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[XORI_0:.*]] = arith.xori %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[XORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -785,10 +757,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ORI_0:.*]] = arith.ori %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -801,10 +770,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ANDI_0:.*]] = arith.andi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ANDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1054,10 +1020,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[MULF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1071,10 +1034,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[MULF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1104,10 +1064,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[MULI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1121,10 +1078,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[MULI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1154,10 +1108,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[ADDF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1171,10 +1122,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 -! CHECK: hlfir.assign %[[ADDF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1218,10 +1166,7 @@ ! CHECK: fir.do_loop %[[VAL_4:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_0]] step %[[CONSTANT_6]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: } @@ -1261,10 +1206,7 @@ ! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_0]] step %[[CONSTANT_4]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> @@ -1296,10 +1238,7 @@ ! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { ! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[DESIGNATE_0]] into %[[DESIGNATE_1]] : !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -1319,10 +1258,7 @@ ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): -! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref -! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref -! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.reduction_combine %[[VAL_1]] into %[[VAL_0]] : !fir.ref ! CHECK: acc.yield %[[VAL_0]] : !fir.ref ! CHECK: } @@ -1884,111 +1820,3 @@ subroutine acc_reduction_logical_allocatable(l) ! CHECK-LABEL: func.func @_QPacc_reduction_logical_allocatable( ! CHECK: %[[REDUCTION_0:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref>>>) recipe(@reduction_lor_ref_box_heap_l32) -> !fir.ref>>> {name = "l"} ! CHECK: acc.parallel reduction(%[[REDUCTION_0]] : !fir.ref>>>) - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_lor_ref_box_heap_l32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_box_UxUxf32 : !fir.box> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_box_ptr_Uxf32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_box_heap_Uxf32 : !fir.ref>>> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box> reduction_operator init { -! ACC_COMBINE-LABEL: } combiner { -! ACC_COMBINE: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): -! ACC_COMBINE: %[[CONSTANT_0:.*]] = arith.constant 1 : index -! ACC_COMBINE: %[[CONSTANT_1:.*]] = arith.constant 1 : index -! ACC_COMBINE: %[[CONSTANT_2:.*]] = arith.constant 3 : index -! ACC_COMBINE: %[[CONSTANT_3:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[CONSTANT_4:.*]] = arith.constant 2 : index -! ACC_COMBINE: %[[CONSTANT_5:.*]] = arith.constant 3 : index -! ACC_COMBINE: %[[CONSTANT_6:.*]] = arith.constant true -! ACC_COMBINE: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1> -! ACC_COMBINE: %[[CONSTANT_7:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box>, index) -> (index, index, index) -! ACC_COMBINE: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_1]] : index -! ACC_COMBINE: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index -! ACC_COMBINE: %[[CONSTANT_8:.*]] = arith.constant 0 : index -! ACC_COMBINE: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_8]] : (!fir.box>, index) -> (index, index, index) -! ACC_COMBINE: %[[ADDI_2:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_1]] : index -! ACC_COMBINE: %[[ADDI_3:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_2]] : index -! ACC_COMBINE: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_2]]:%[[ADDI_3]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> -! ACC_COMBINE: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> -! ACC_COMBINE: %[[CONSTANT_9:.*]] = arith.constant 1 : index -! ACC_COMBINE: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_9]] to %[[CONSTANT_5]] step %[[CONSTANT_9]] unordered { -! ACC_COMBINE: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! ACC_COMBINE: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref -! ACC_COMBINE: acc.reduction_combine %[[DESIGNATE_2]] into %[[DESIGNATE_3]] : !fir.ref -! ACC_COMBINE: } -! ACC_COMBINE: acc.yield %[[VAL_0]] : !fir.box> -! ACC_COMBINE: } - - -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_box_Uxi32 : !fir.box> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_section_lb10.ub19_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_box_ptr_i32 : !fir.ref>> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ptr -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_box_heap_i32 : !fir.ref>> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.heap -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref> -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref> -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE-NOT: acc.reduction_combine -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref> reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref -! ACC_COMBINE-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref reduction_operator init { -! ACC_COMBINE: acc.reduction_combine %{{.*}} into %{{.*}} : !fir.ref From ef1b46f29293db7b16dee598fb1e8f2a62555c33 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Fri, 10 Jul 2026 11:05:29 +0200 Subject: [PATCH 102/125] [Clang] Fix a crash when checking the constraints of a self-referential concept (#208465) Mark self-referencial concepts as invalid to prevent them from being evaluated (which would crash). Fixes #206336 --- clang/lib/Sema/SemaTemplate.cpp | 1 + clang/test/CXX/drs/cwg25xx.cpp | 6 ------ clang/test/SemaTemplate/concepts.cpp | 28 ++++++++++++++++++++++------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 43bcd0bfb9e17..a7f252be1cb39 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -9321,6 +9321,7 @@ bool Sema::CheckConceptUseInDefinition(NamedDecl *Concept, SourceLocation Loc) { CE && !CE->isInvalidDecl() && !CE->hasDefinition()) { Diag(Loc, diag::err_recursive_concept) << CE; Diag(CE->getLocation(), diag::note_declared_at); + CE->setInvalidDecl(); return true; } // Concept template parameters don't have a definition and can't diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index d5219bcd74756..6b4b167d8f07f 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -247,9 +247,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 x; }; static_assert(ErrorRequires); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'ErrorRequires'}} \ - // since-cxx20-note@#cwg2565-expr {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} template concept NestedErrorInRequires = requires (T x) { // #cwg2565-NEIR @@ -261,9 +258,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 }; }; static_assert(NestedErrorInRequires); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'NestedErrorInRequires'}} \ - // since-cxx20-note-re@#cwg2565-NEIR-inner {{because {{.*}} would be invalid: constraint depends on a previously diagnosed expression}} #endif } // namespace cwg2565 diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 6f7f00bf12e61..f2478e1a22a6a 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -997,7 +997,7 @@ template concept True = true; template -concept False = false; // expected-note 9 {{'false' evaluated to false}} +concept False = false; // expected-note 8 {{'false' evaluated to false}} template concept Irrelevant = false; @@ -1009,8 +1009,8 @@ concept ErrorRequires = requires(ErrorRequires auto x) { x; }; //#GH54678-ill-fo // expected-note@-1 {{declared here}} template concept C1 = C1 && [](C1 auto) -> C1 auto {}; -//expected-error@-1 4{{a concept definition cannot refer to itself}} \ -//expected-note@-1 4{{declared here}} +//expected-error@-1 {{a concept definition cannot refer to itself}} \ +//expected-note@-1 {{declared here}} template void aaa(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (False || False) || False {} // expected-note 3 {{'int' does not satisfy 'False'}} @@ -1023,15 +1023,15 @@ requires (Irrelevant || True) && False {} // expected-note {{'int' does template void eee(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (Irrelevant || Irrelevant || True) && False {} // expected-note {{'long' does not satisfy 'False'}} -template void fff(T t) // expected-note {{candidate template ignored: constraints not satisfied}} -requires((ErrorRequires || False || True) && False) {} // expected-note {{because 'unsigned long' does not satisfy 'False'}} +template void fff(T t) +requires((ErrorRequires || False || True) && False) {} void test() { aaa(42); // expected-error {{no matching function}} bbb(42L); // expected-error{{no matching function}} ccc(42UL); // expected-error {{no matching function}} ddd(42); // expected-error {{no matching function}} eee(42L); // expected-error {{no matching function}} - fff(42UL); // expected-error {{no matching function}} + fff(42UL); } } @@ -2064,3 +2064,19 @@ auto x = quantity{}, int>{}; } // namespace CannotResolve1 } // namespace GH175831 + + +namespace GH206336 { +class Dim; +struct S; +template concept foo = true; +template concept SS = false; // expected-note {{because 'false' evaluated to false}} +template concept _Dim = _Dim; // expected-error {{a concept definition cannot refer to itself}} \ + // expected-note {{declared here}} +template E> auto bar(Dim, E) {}; // expected-note {{candidate template ignored: constraints not satisfied}} \ + // expected-note {{because 'GH206336::S' does not satisfy 'SS'}} + +void baz() { + auto qux = bar(true, [] {}); // expected-error {{no matching function for call to 'bar'}} +} +} From 642b85388cca2114e467c58c02fe79b32f7b221f Mon Sep 17 00:00:00 2001 From: Shatyuka Date: Fri, 10 Jul 2026 17:08:02 +0800 Subject: [PATCH 103/125] [DWARFLinkerParallel] Add missing version string in producer (#158195) Add missing LLVM version string to `DW_AT_producer` in `__artificial_type_unit`. --------- Co-authored-by: Jonas Devlieghere --- .../Parallel/DWARFLinkerTypeUnit.cpp | 9 ++++----- .../X86/DWARFLinkerParallel/odr-uniquing.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp index eae1e11a6d39f..58de4e91570df 100644 --- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp +++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerTypeUnit.cpp @@ -58,12 +58,11 @@ void TypeUnit::createDIETree(BumpPtrAllocator &Allocator) { uint64_t OutOffset = getDebugInfoHeaderSize(); UnitDIE->setOffset(OutOffset); - SmallString<200> ProducerString; - ProducerString += "llvm DWARFLinkerParallel library version "; + const char *ProducerString = + "llvm DWARFLinkerParallel library version " LLVM_VERSION_STRING; DebugInfoSection.notePatchWithOffsetUpdate( - DebugStrPatch{ - {OutOffset}, - GlobalData.getStringPool().insert(ProducerString.str()).first}, + DebugStrPatch{{OutOffset}, + GlobalData.getStringPool().insert(ProducerString).first}, PatchesOffsets); OutOffset += DIETreeGenerator .addStringPlaceholderAttribute(dwarf::DW_AT_producer, diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp index 17833fe3a7d2d..5358fa8a658bd 100644 --- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp +++ b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-uniquing.cpp @@ -252,15 +252,15 @@ void foo() { // CHECK:0x00000064: "u" // CHECK:0x00000066: "AnonC" // CHECK:0x0000006c: "(anonymous namespace)" -// CHECK:0x00000082: "llvm DWARFLinkerParallel library version " -// CHECK:0x000000ac: "__artificial_type_unit" -// CHECK:0x000000c3: "" -// CHECK:0x000000c4: "AliasForS" -// CHECK:0x000000ce: "C" -// CHECK:0x000000d0: "N" -// CHECK:0x000000d2: "Nested" -// CHECK:0x000000d9: "S" -// CHECK:0x000000db: "U" +// CHECK:0x00000082: "llvm DWARFLinkerParallel library version +// CHECK: "__artificial_type_unit" +// CHECK: "" +// CHECK: "AliasForS" +// CHECK: "C" +// CHECK: "N" +// CHECK: "Nested" +// CHECK: "S" +// CHECK: "U" // CHECK:.apple_names From 83c5973a0a9e849efdec168a1b712f355e59ff4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20K=C3=A9ri?= Date: Fri, 10 Jul 2026 11:19:43 +0200 Subject: [PATCH 104/125] [clang][analyzer] Fixed 'if_nameindex' in MallocChecker (#207726) The function `if_nameindex` has 0 arguments but `MallocChecker` expected it to have 1 argument and was not recognized by the checker correctly. --- .../lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 2 +- clang/test/Analysis/malloc-failure.c | 2 +- clang/test/Analysis/malloc.c | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 7ea028246a2ee..287824984623c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -547,7 +547,7 @@ class MallocChecker {{CDM::CLibrary, {"strdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"_strdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"kmalloc"}, 2}, &MallocChecker::checkKernelMalloc}, - {{CDM::CLibrary, {"if_nameindex"}, 1}, &MallocChecker::checkIfNameIndex}, + {{CDM::CLibrary, {"if_nameindex"}, 0}, &MallocChecker::checkIfNameIndex}, {{CDM::CLibrary, {"wcsdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"_wcsdup"}, 1}, &MallocChecker::checkStrdup}, {{CDM::CLibrary, {"g_malloc"}, 1}, &MallocChecker::checkBasicAlloc}, diff --git a/clang/test/Analysis/malloc-failure.c b/clang/test/Analysis/malloc-failure.c index bf421fe7672c8..aea58dad470fa 100644 --- a/clang/test/Analysis/malloc-failure.c +++ b/clang/test/Analysis/malloc-failure.c @@ -71,6 +71,6 @@ void test_strdup() { void test_ifnameindex() { struct if_nameindex *p = if_nameindex(); - p->x = 1; //FIXME: if_nameindex is not recognized by the checker + p->x = 1; //expected-warning{{dereference of a null pointer}} if_freenameindex(p); } diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index 849ab3a3a0f37..a75144f041de0 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -1018,6 +1018,21 @@ void testWinWcsdupContentIsDefined(const wchar_t *s, unsigned validIndex) { free(s2); } +struct if_nameindex { char x; }; +struct if_nameindex *if_nameindex(void); +void if_freenameindex(struct if_nameindex *ptr); + +char testIfnameindex() { + struct if_nameindex *i = if_nameindex(); + return i->x; // expected-warning {{Potential leak of memory pointed to by}} +} + +void testIffreenameindex() { + struct if_nameindex *i = if_nameindex(); + char x = i->x; + if_freenameindex(i); +} // no warning + // ---------------------------------------------------------------------------- // Test the system library functions to which the pointer can escape. // This tests false positive suppression. From 9a92a2be8d4938f08ba8c98c222764a8fd14746d Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan Date: Fri, 10 Jul 2026 10:35:14 +0100 Subject: [PATCH 105/125] [lldb] Implement LLDB_REGNUM_GENERIC_TP conversion for Aarch64 (#208643) LLDB currently fails to find TLS variables on Linux, and this is part of the problem. --- lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp | 1 + lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp index 72d03e2348e59..8226bb6aea424 100644 --- a/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -88,6 +88,7 @@ uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) { .Cases({"sp", "x31"}, LLDB_REGNUM_GENERIC_SP) .Cases({"fp", "x29"}, LLDB_REGNUM_GENERIC_FP) .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS) + .Case("tpidr", LLDB_REGNUM_GENERIC_TP) .Case("x0", LLDB_REGNUM_GENERIC_ARG1) .Case("x1", LLDB_REGNUM_GENERIC_ARG2) .Case("x2", LLDB_REGNUM_GENERIC_ARG3) diff --git a/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp b/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp index 5f9332e3e85bd..06176de68a336 100644 --- a/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp +++ b/lldb/unittests/ABI/AArch64/ABIAArch64Test.cpp @@ -66,6 +66,23 @@ TEST_P(ABIAArch64TestFixture, AugmentRegisterInfo) { EXPECT_EQ(new_pc.regnum_dwarf, arm64_dwarf::pc); } +TEST_P(ABIAArch64TestFixture, AugmentRegisterInfoThreadPointer) { + ABISP abi_sp = ABI::FindPlugin(ProcessSP(), ArchSpec(GetParam())); + ASSERT_TRUE(abi_sp); + using Register = DynamicRegisterInfo::Register; + + Register tpidr; + tpidr.name = ConstString("tpidr"); + tpidr.set_name = ConstString("GPR"); + std::vector regs{tpidr}; + + abi_sp->AugmentRegisterInfo(regs); + + ASSERT_EQ(regs.size(), 1U); + EXPECT_EQ(regs[0].regnum_generic, + static_cast(LLDB_REGNUM_GENERIC_TP)); +} + INSTANTIATE_TEST_SUITE_P(ABIAArch64Tests, ABIAArch64TestFixture, testing::Values("aarch64-pc-linux", "arm64-apple-macosx")); From 9b9b19364dfb5ba2984a0970928b7ad95569e88a Mon Sep 17 00:00:00 2001 From: Charles Zablit Date: Fri, 10 Jul 2026 11:41:53 +0200 Subject: [PATCH 106/125] [X86][Disassembler] Reject instructions longer than 15 bytes (#208277) An x86 instruction can be at most 15 bytes. The decoder already checks for overruns but only emits an `LLVM_DEBUG` message and still returns `Success`. This patch returns `Fail` instead, so `getInstruction()` never reports a size that isn't a valid instruction length. --- llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp | 4 +++- llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index d499dc43dcab6..1d83ee40b9bc1 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -1835,8 +1835,10 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction( Insn.operands = x86OperandSets[Insn.spec->operands]; Insn.length = Insn.readerCursor - Insn.startLocation; Size = Insn.length; - if (Size > 15) + if (Size > 15) { LLVM_DEBUG(dbgs() << "Instruction exceeds 15-byte limit"); + return Fail; + } bool Ret = translateInstruction(Instr, Insn, this); if (!Ret) { diff --git a/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt b/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt new file mode 100644 index 0000000000000..cd441eca022c0 --- /dev/null +++ b/llvm/test/MC/Disassembler/X86/x86-64-instruction-length.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=x86_64 2>&1 | FileCheck %s + +## 15 redundant operand-size (0x66) prefixes + NOP = 16 bytes, over the limit. +# CHECK: warning: invalid instruction encoding +0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x90 From e2e81d96daa327f1ab7e28ef7a8cf929382cc1d2 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 10 Jul 2026 10:45:21 +0100 Subject: [PATCH 107/125] [X86] combine-pmaddwd.ll - test with x86-64 levels not raw SSE levels (#208666) Add missing AVX512 coverage --- llvm/test/CodeGen/X86/combine-pmaddwd.ll | 220 +++++++++++++++-------- 1 file changed, 142 insertions(+), 78 deletions(-) diff --git a/llvm/test/CodeGen/X86/combine-pmaddwd.ll b/llvm/test/CodeGen/X86/combine-pmaddwd.ll index d1e5e720af7fb..4fe3569df88e9 100644 --- a/llvm/test/CodeGen/X86/combine-pmaddwd.ll +++ b/llvm/test/CodeGen/X86/combine-pmaddwd.ll @@ -1,8 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE,SSE41 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=CHECK,AVX,AVX1 -; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE42 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=sandybridge | FileCheck %s --check-prefixes=CHECK,AVX,AVX1 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,AVX,AVX2 +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,AVX,AVX512 define <4 x i32> @combine_pmaddwd_zero(<8 x i16> %a0, <8 x i16> %a1) { ; SSE-LABEL: combine_pmaddwd_zero: @@ -53,6 +54,13 @@ define <8 x i32> @combine_pmaddwd_concat(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> ; AVX2-NEXT: vpmaddwd %xmm3, %xmm2, %xmm1 ; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpmaddwd %xmm3, %xmm2, %xmm1 +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 +; AVX512-NEXT: retq %1 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> %a1) %2 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a2, <8 x i16> %a3) %3 = shufflevector <4 x i32> %1, <4 x i32> %2, <8 x i32> @@ -60,19 +68,12 @@ define <8 x i32> @combine_pmaddwd_concat(<8 x i16> %a0, <8 x i16> %a1, <8 x i16> } define <8 x i32> @combine_pmaddwd_concat_freeze(<8 x i16> %a0, <8 x i16> %a1) { -; SSE2-LABEL: combine_pmaddwd_concat_freeze: -; SSE2: # %bb.0: -; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE2-NEXT: pmaddwd %xmm2, %xmm0 -; SSE2-NEXT: pmaddwd %xmm2, %xmm1 -; SSE2-NEXT: retq -; -; SSE41-LABEL: combine_pmaddwd_concat_freeze: -; SSE41: # %bb.0: -; SSE41-NEXT: pmovsxbw {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE41-NEXT: pmaddwd %xmm2, %xmm0 -; SSE41-NEXT: pmaddwd %xmm2, %xmm1 -; SSE41-NEXT: retq +; SSE-LABEL: combine_pmaddwd_concat_freeze: +; SSE: # %bb.0: +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] +; SSE-NEXT: pmaddwd %xmm2, %xmm0 +; SSE-NEXT: pmaddwd %xmm2, %xmm1 +; SSE-NEXT: retq ; ; AVX1-LABEL: combine_pmaddwd_concat_freeze: ; AVX1: # %bb.0: @@ -88,6 +89,13 @@ define <8 x i32> @combine_pmaddwd_concat_freeze(<8 x i16> %a0, <8 x i16> %a1) { ; AVX2-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat_freeze: +; AVX512: # %bb.0: +; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 def $ymm0 +; AVX512-NEXT: vinserti128 $1, %xmm1, %ymm0, %ymm0 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +; AVX512-NEXT: retq %lo = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> ) %hi = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a1, <8 x i16> ) %flo = freeze <4 x i32> %lo @@ -113,11 +121,11 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; SSE2-NEXT: pshufhw {{.*#+}} xmm0 = xmm0[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[0,2,2,3] ; SSE2-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE2-NEXT: pshuflw {{.*#+}} xmm2 = mem[0,2,2,3,4,5,6,7] ; SSE2-NEXT: pmaddwd %xmm1, %xmm0 -; SSE2-NEXT: pshuflw {{.*#+}} xmm1 = mem[0,2,2,3,4,5,6,7] -; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm1[0,1,2,3,4,6,6,7] -; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] +; SSE2-NEXT: pshufhw {{.*#+}} xmm1 = xmm2[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshuflw {{.*#+}} xmm2 = mem[0,2,2,3,4,5,6,7] +; SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm1[0,2,2,3] ; SSE2-NEXT: pshufhw {{.*#+}} xmm2 = xmm2[0,1,2,3,4,6,6,7] ; SSE2-NEXT: pshufd {{.*#+}} xmm2 = xmm2[0,2,2,3] ; SSE2-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3] @@ -131,32 +139,32 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; SSE2-NEXT: pmaddwd %xmm2, %xmm1 ; SSE2-NEXT: retq ; -; SSE41-LABEL: combine_pmaddwd_concat_add: -; SSE41: # %bb.0: -; SSE41-NEXT: movdqa (%rdi), %xmm0 -; SSE41-NEXT: movdqa 16(%rdi), %xmm1 -; SSE41-NEXT: movdqa 32(%rdi), %xmm2 -; SSE41-NEXT: movdqa 48(%rdi), %xmm3 -; SSE41-NEXT: movdqa (%rsi), %xmm4 -; SSE41-NEXT: movdqa 16(%rsi), %xmm5 -; SSE41-NEXT: movdqa 32(%rsi), %xmm6 -; SSE41-NEXT: movdqa 48(%rsi), %xmm7 -; SSE41-NEXT: movq {{.*#+}} xmm8 = [0,1,4,5,8,9,12,13,0,0,0,0,0,0,0,0] -; SSE41-NEXT: pshufb %xmm8, %xmm6 -; SSE41-NEXT: pshufb %xmm8, %xmm4 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3] -; SSE41-NEXT: pshufb %xmm8, %xmm2 -; SSE41-NEXT: pshufb %xmm8, %xmm0 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] -; SSE41-NEXT: pmaddwd %xmm4, %xmm0 -; SSE41-NEXT: pshufb %xmm8, %xmm7 -; SSE41-NEXT: pshufb %xmm8, %xmm5 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm7[0],xmm5[1],xmm7[1],xmm5[2],xmm7[2],xmm5[3],xmm7[3] -; SSE41-NEXT: pshufb %xmm8, %xmm3 -; SSE41-NEXT: pshufb %xmm8, %xmm1 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] -; SSE41-NEXT: pmaddwd %xmm5, %xmm1 -; SSE41-NEXT: retq +; SSE42-LABEL: combine_pmaddwd_concat_add: +; SSE42: # %bb.0: +; SSE42-NEXT: movdqa (%rdi), %xmm0 +; SSE42-NEXT: movdqa 16(%rdi), %xmm1 +; SSE42-NEXT: movdqa 32(%rdi), %xmm2 +; SSE42-NEXT: movdqa 48(%rdi), %xmm3 +; SSE42-NEXT: movdqa (%rsi), %xmm4 +; SSE42-NEXT: movdqa 16(%rsi), %xmm5 +; SSE42-NEXT: movdqa 32(%rsi), %xmm6 +; SSE42-NEXT: movdqa 48(%rsi), %xmm7 +; SSE42-NEXT: movq {{.*#+}} xmm8 = [0,1,4,5,8,9,12,13,0,0,0,0,0,0,0,0] +; SSE42-NEXT: pshufb %xmm8, %xmm6 +; SSE42-NEXT: pshufb %xmm8, %xmm4 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1],xmm4[2],xmm6[2],xmm4[3],xmm6[3] +; SSE42-NEXT: pshufb %xmm8, %xmm2 +; SSE42-NEXT: pshufb %xmm8, %xmm0 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1],xmm0[2],xmm2[2],xmm0[3],xmm2[3] +; SSE42-NEXT: pmaddwd %xmm4, %xmm0 +; SSE42-NEXT: pshufb %xmm8, %xmm7 +; SSE42-NEXT: pshufb %xmm8, %xmm5 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm5 = xmm5[0],xmm7[0],xmm5[1],xmm7[1],xmm5[2],xmm7[2],xmm5[3],xmm7[3] +; SSE42-NEXT: pshufb %xmm8, %xmm3 +; SSE42-NEXT: pshufb %xmm8, %xmm1 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm3[0],xmm1[1],xmm3[1],xmm1[2],xmm3[2],xmm1[3],xmm3[3] +; SSE42-NEXT: pmaddwd %xmm5, %xmm1 +; SSE42-NEXT: retq ; ; AVX1-LABEL: combine_pmaddwd_concat_add: ; AVX1: # %bb.0: @@ -195,6 +203,16 @@ define <8 x i32> @combine_pmaddwd_concat_add(ptr %px0, ptr %py0) { ; AVX2-NEXT: vpmaddwd 32(%rdi), %ymm0, %ymm0 ; AVX2-NEXT: vpaddd %ymm0, %ymm1, %ymm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_concat_add: +; AVX512: # %bb.0: +; AVX512-NEXT: vpxor %xmm0, %xmm0, %xmm0 +; AVX512-NEXT: vpblendw {{.*#+}} ymm1 = mem[0],ymm0[1],mem[2],ymm0[3],mem[4],ymm0[5],mem[6],ymm0[7],mem[8],ymm0[9],mem[10],ymm0[11],mem[12],ymm0[13],mem[14],ymm0[15] +; AVX512-NEXT: vpmaddwd (%rdi), %ymm1, %ymm1 +; AVX512-NEXT: vpblendw {{.*#+}} ymm0 = mem[0],ymm0[1],mem[2],ymm0[3],mem[4],ymm0[5],mem[6],ymm0[7],mem[8],ymm0[9],mem[10],ymm0[11],mem[12],ymm0[13],mem[14],ymm0[15] +; AVX512-NEXT: vpmaddwd 32(%rdi), %ymm0, %ymm0 +; AVX512-NEXT: vpaddd %ymm0, %ymm1, %ymm0 +; AVX512-NEXT: retq %px1 = getelementptr inbounds nuw i8, ptr %px0, i64 16 %py1 = getelementptr inbounds nuw i8, ptr %py0, i64 16 %px2 = getelementptr inbounds nuw i8, ptr %px0, i64 32 @@ -241,6 +259,12 @@ define <4 x i32> @combine_pmaddwd_demandedelts(<8 x i16> %a0, <8 x i16> %a1) { ; AVX2-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 ; AVX2-NEXT: vpbroadcastd %xmm0, %xmm0 ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_pmaddwd_demandedelts: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd %xmm1, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastd %xmm0, %xmm0 +; AVX512-NEXT: retq %1 = shufflevector <8 x i16> %a0, <8 x i16> poison, <8 x i32> %2 = shufflevector <8 x i16> %a1, <8 x i16> poison, <8 x i32> %3 = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %1, <8 x i16> %2) @@ -283,10 +307,31 @@ define <4 x i32> @combine_pmaddwd_constant_nsw() { ; Constant folding PMADDWD was causing an infinite loop in the PCMPGT commuting between 2 constant values. define i1 @pmaddwd_pcmpgt_infinite_loop() { -; CHECK-LABEL: pmaddwd_pcmpgt_infinite_loop: -; CHECK: # %bb.0: -; CHECK-NEXT: movb $1, %al -; CHECK-NEXT: retq +; SSE-LABEL: pmaddwd_pcmpgt_infinite_loop: +; SSE: # %bb.0: +; SSE-NEXT: movb $1, %al +; SSE-NEXT: retq +; +; AVX1-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX1: # %bb.0: +; AVX1-NEXT: movb $1, %al +; AVX1-NEXT: retq +; +; AVX2-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX2: # %bb.0: +; AVX2-NEXT: movb $1, %al +; AVX2-NEXT: retq +; +; AVX512-LABEL: pmaddwd_pcmpgt_infinite_loop: +; AVX512: # %bb.0: +; AVX512-NEXT: vpxor %xmm0, %xmm0, %xmm0 +; AVX512-NEXT: vpbroadcastd {{.*#+}} xmm1 = [2147483647,2147483647,2147483647,2147483647] +; AVX512-NEXT: vpaddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 # [4294967288,4294967287,4294967286,4294967285] +; AVX512-NEXT: vpcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %k1 +; AVX512-NEXT: vpcmpgtd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %k0 {%k1} +; AVX512-NEXT: kortestb %k0, %k0 +; AVX512-NEXT: sete %al +; AVX512-NEXT: retq %1 = tail call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> , <8 x i16> ) %2 = icmp eq <4 x i32> %1, %3 = select <4 x i1> %2, <4 x i32> , <4 x i32> zeroinitializer @@ -301,19 +346,12 @@ define i1 @pmaddwd_pcmpgt_infinite_loop() { ; If the shuffle matches, but there is no multiply, introduce a trivial multiply by 1. define <8 x i32> @sext_pairwise_add(<16 x i16> %x) { -; SSE2-LABEL: sext_pairwise_add: -; SSE2: # %bb.0: -; SSE2-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE2-NEXT: pmaddwd %xmm2, %xmm0 -; SSE2-NEXT: pmaddwd %xmm2, %xmm1 -; SSE2-NEXT: retq -; -; SSE41-LABEL: sext_pairwise_add: -; SSE41: # %bb.0: -; SSE41-NEXT: pmovsxbw {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] -; SSE41-NEXT: pmaddwd %xmm2, %xmm0 -; SSE41-NEXT: pmaddwd %xmm2, %xmm1 -; SSE41-NEXT: retq +; SSE-LABEL: sext_pairwise_add: +; SSE: # %bb.0: +; SSE-NEXT: movdqa {{.*#+}} xmm2 = [1,1,1,1,1,1,1,1] +; SSE-NEXT: pmaddwd %xmm2, %xmm0 +; SSE-NEXT: pmaddwd %xmm2, %xmm1 +; SSE-NEXT: retq ; ; AVX1-LABEL: sext_pairwise_add: ; AVX1: # %bb.0: @@ -328,6 +366,11 @@ define <8 x i32> @sext_pairwise_add(<16 x i16> %x) { ; AVX2: # %bb.0: ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: sext_pairwise_add: +; AVX512: # %bb.0: +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] +; AVX512-NEXT: retq %1 = sext <16 x i16> %x to <16 x i32> %2 = shufflevector <16 x i32> %1, <16 x i32> poison, <8 x i32> %3 = shufflevector <16 x i32> %1, <16 x i32> poison, <8 x i32> @@ -356,6 +399,11 @@ define <8 x i32> @combine_with_mul(<16 x i16> %v) { ; AVX2: # %bb.0: # %bb1 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_mul: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = mul nsw <16 x i32> %0, @@ -386,6 +434,11 @@ define <8 x i32> @combine_with_shl(<16 x i16> %v) { ; AVX2: # %bb.0: # %bb1 ; AVX2-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_shl: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmaddwd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %ymm0, %ymm0 # [4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1,4096,1] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = shl nsw <16 x i32> %0, @@ -415,21 +468,21 @@ define <8 x i32> @combine_with_shl_overflow(<16 x i16> %v) { ; SSE2-NEXT: paddd %xmm4, %xmm0 ; SSE2-NEXT: retq ; -; SSE41-LABEL: combine_with_shl_overflow: -; SSE41: # %bb.0: # %bb1 -; SSE41-NEXT: pxor %xmm2, %xmm2 -; SSE41-NEXT: pxor %xmm4, %xmm4 -; SSE41-NEXT: punpckhwd {{.*#+}} xmm4 = xmm4[4],xmm1[4],xmm4[5],xmm1[5],xmm4[6],xmm1[6],xmm4[7],xmm1[7] -; SSE41-NEXT: pxor %xmm3, %xmm3 -; SSE41-NEXT: punpcklwd {{.*#+}} xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3] -; SSE41-NEXT: phaddd %xmm4, %xmm3 -; SSE41-NEXT: pxor %xmm1, %xmm1 -; SSE41-NEXT: punpckhwd {{.*#+}} xmm1 = xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7] -; SSE41-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm0[0],xmm2[1],xmm0[1],xmm2[2],xmm0[2],xmm2[3],xmm0[3] -; SSE41-NEXT: phaddd %xmm1, %xmm2 -; SSE41-NEXT: movdqa %xmm2, %xmm0 -; SSE41-NEXT: movdqa %xmm3, %xmm1 -; SSE41-NEXT: retq +; SSE42-LABEL: combine_with_shl_overflow: +; SSE42: # %bb.0: # %bb1 +; SSE42-NEXT: pxor %xmm3, %xmm3 +; SSE42-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7] +; SSE42-NEXT: pxor %xmm2, %xmm2 +; SSE42-NEXT: punpcklwd {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1],xmm2[2],xmm1[2],xmm2[3],xmm1[3] +; SSE42-NEXT: phaddd %xmm3, %xmm2 +; SSE42-NEXT: pxor %xmm1, %xmm1 +; SSE42-NEXT: pxor %xmm3, %xmm3 +; SSE42-NEXT: punpckhwd {{.*#+}} xmm3 = xmm3[4],xmm0[4],xmm3[5],xmm0[5],xmm3[6],xmm0[6],xmm3[7],xmm0[7] +; SSE42-NEXT: punpcklwd {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3] +; SSE42-NEXT: phaddd %xmm3, %xmm1 +; SSE42-NEXT: movdqa %xmm1, %xmm0 +; SSE42-NEXT: movdqa %xmm2, %xmm1 +; SSE42-NEXT: retq ; ; AVX1-LABEL: combine_with_shl_overflow: ; AVX1: # %bb.0: # %bb1 @@ -456,6 +509,15 @@ define <8 x i32> @combine_with_shl_overflow(<16 x i16> %v) { ; AVX2-NEXT: vphaddd %ymm0, %ymm1, %ymm0 ; AVX2-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] ; AVX2-NEXT: retq +; +; AVX512-LABEL: combine_with_shl_overflow: +; AVX512: # %bb.0: # %bb1 +; AVX512-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero +; AVX512-NEXT: vpslld $16, %zmm0, %zmm0 +; AVX512-NEXT: vextracti64x4 $1, %zmm0, %ymm1 +; AVX512-NEXT: vphaddd %ymm1, %ymm0, %ymm0 +; AVX512-NEXT: vpermq {{.*#+}} ymm0 = ymm0[0,2,1,3] +; AVX512-NEXT: retq bb1: %0 = sext <16 x i16> %v to <16 x i32> %1 = shl nsw <16 x i32> %0, splat (i32 16) @@ -464,3 +526,5 @@ bb1: %4 = add <8 x i32> %2, %3 ret <8 x i32> %4 } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK: {{.*}} From 4f3000e8d6d07a1fa9d3cdfde34a270bd0a2decf Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Fri, 10 Jul 2026 11:46:33 +0200 Subject: [PATCH 108/125] [mlir][SPIR-V] Add spirv.GL.NMax/NMin to SPIRVtoLLVM conversion (#205976) --- .../Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp | 2 ++ .../SPIRVToLLVM/gl-ops-to-llvm.mlir | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp index 8b113478be71d..fdde3352c040b 100644 --- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp +++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp @@ -2035,6 +2035,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns( ClampPattern, DirectConversionPattern, DirectConversionPattern, + DirectConversionPattern, + DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, diff --git a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir index 7be0bf201175f..08c7947861cb4 100644 --- a/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir +++ b/mlir/test/Conversion/SPIRVToLLVM/gl-ops-to-llvm.mlir @@ -103,6 +103,32 @@ spirv.func @fclamp(%arg0: f32, %arg1: f32, %arg2: f32) "None" { spirv.Return } +//===----------------------------------------------------------------------===// +// spirv.GL.NMax +//===----------------------------------------------------------------------===// + +// CHECK-LABEL: @nmax +spirv.func @nmax(%arg0: f32, %arg1: vector<3xf16>) "None" { + // CHECK: llvm.intr.maxnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %0 = spirv.GL.NMax %arg0, %arg0 : f32 + // CHECK: llvm.intr.maxnum(%{{.*}}, %{{.*}}) : (vector<3xf16>, vector<3xf16>) -> vector<3xf16> + %1 = spirv.GL.NMax %arg1, %arg1 : vector<3xf16> + spirv.Return +} + +//===----------------------------------------------------------------------===// +// spirv.GL.NMin +//===----------------------------------------------------------------------===// + +// CHECK-LABEL: @nmin +spirv.func @nmin(%arg0: f32, %arg1: vector<3xf16>) "None" { + // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %0 = spirv.GL.NMin %arg0, %arg0 : f32 + // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (vector<3xf16>, vector<3xf16>) -> vector<3xf16> + %1 = spirv.GL.NMin %arg1, %arg1 : vector<3xf16> + spirv.Return +} + //===----------------------------------------------------------------------===// // spirv.GL.Log //===----------------------------------------------------------------------===// From 587db92f50dfafea5d580d7b53111b5ac5f61e81 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 10 Jul 2026 10:50:00 +0100 Subject: [PATCH 109/125] [CostModel][X86] intrinsic-cost-kinds.ll - add pdep/pext test coverage (#208668) Ensure x86 has pdep/pext cost coverage for #207657 NOTE: This is mainly a crash/sanity testfile, they aren't necessarily accurate --- .../CostModel/X86/intrinsic-cost-kinds.ll | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll index 243d0df816f5e..45e19b93e41cf 100644 --- a/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll +++ b/llvm/test/Analysis/CostModel/X86/intrinsic-cost-kinds.ll @@ -308,6 +308,58 @@ define void @fshl(i32 %a, i32 %b, i32 %c, <16 x i32> %va, <16 x i32> %vb, <16 x ret void } +define void @pdep(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) { +; THRU-LABEL: 'pdep' +; THRU-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; THRU-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; THRU-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void +; +; LATE-LABEL: 'pdep' +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE-LABEL: 'pdep' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; SIZE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE_LATE-LABEL: 'pdep' +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; + %s = call i32 @llvm.pdep.i32(i32 %a, i32 %b) + %v = call <16 x i32> @llvm.pdep.v16i32(<16 x i32> %va, <16 x i32> %vb) + ret void +} + +define void @pext(i32 %a, i32 %b, <16 x i32> %va, <16 x i32> %vb) { +; THRU-LABEL: 'pext' +; THRU-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; THRU-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; THRU-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void +; +; LATE-LABEL: 'pext' +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE-LABEL: 'pext' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; SIZE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; +; SIZE_LATE-LABEL: 'pext' +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 100 for instruction: %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) +; SIZE_LATE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret void +; + %s = call i32 @llvm.pext.i32(i32 %a, i32 %b) + %v = call <16 x i32> @llvm.pext.v16i32(<16 x i32> %va, <16 x i32> %vb) + ret void +} + define void @maskedgather(<16 x ptr> %va, <16 x i1> %vb, <16 x float> %vc) { ; THRU-LABEL: 'maskedgather' ; THRU-NEXT: Cost Model: Found an estimated cost of 61 for instruction: %v = call <16 x float> @llvm.masked.gather.v16f32.v16p0(<16 x ptr> align 1 %va, <16 x i1> %vb, <16 x float> %vc) From 50143b877dffdb9016e50fb541806eb59c261b10 Mon Sep 17 00:00:00 2001 From: Arseniy Obolenskiy Date: Fri, 10 Jul 2026 11:52:48 +0200 Subject: [PATCH 110/125] [mlir][SPIR-V] Add SPIRVToLLVM conversions for CL copysign and fmod ops (#205993) --- mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp | 2 ++ mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp index fdde3352c040b..0822c44c10f1d 100644 --- a/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp +++ b/mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp @@ -2085,6 +2085,8 @@ void mlir::populateSPIRVToLLVMConversionPatterns( DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, + DirectConversionPattern, + DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, DirectConversionPattern, diff --git a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir index a986be42a5437..e6fed930268d4 100644 --- a/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir +++ b/mlir/test/Conversion/SPIRVToLLVM/cl-ops-to-llvm.mlir @@ -69,6 +69,10 @@ spirv.func @cl_binary_float(%arg0: f32, %arg1: f32) "None" { %2 = spirv.CL.fmax %arg0, %arg1 : f32 // CHECK: llvm.intr.minnum(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 %3 = spirv.CL.fmin %arg0, %arg1 : f32 + // CHECK: llvm.intr.copysign(%{{.*}}, %{{.*}}) : (f32, f32) -> f32 + %4 = spirv.CL.copysign %arg0, %arg1 : f32 + // CHECK: llvm.frem %{{.*}}, %{{.*}} : f32 + %5 = spirv.CL.fmod %arg0, %arg1 : f32 spirv.Return } From 99fb741b6e0da866bf3c6000531104bff347d787 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 10 Jul 2026 11:57:15 +0200 Subject: [PATCH 111/125] [libc] Use internal::clock_gettime in socketopt_test (#208667) The external entry point is not available in overlay mode, causing this test to not run there. Other tests also use the internal function. --- libc/test/src/sys/socket/linux/CMakeLists.txt | 2 +- libc/test/src/sys/socket/linux/socketopt_test.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt index 44b9fea16a40d..1f28b99601e61 100644 --- a/libc/test/src/sys/socket/linux/CMakeLists.txt +++ b/libc/test/src/sys/socket/linux/CMakeLists.txt @@ -129,10 +129,10 @@ add_libc_unittest( libc.src.sys.socket.socket libc.src.sys.socket.socketpair libc.src.sys.socket.recv - libc.src.time.clock_gettime libc.src.unistd.close libc.src.unistd.pipe libc.src.__support.CPP.scope + libc.src.__support.time.clock_gettime libc.test.UnitTest.ErrnoCheckingTest libc.test.UnitTest.ErrnoSetterMatcher ) diff --git a/libc/test/src/sys/socket/linux/socketopt_test.cpp b/libc/test/src/sys/socket/linux/socketopt_test.cpp index 3af47c3f18a7d..8fd03c2cf24d4 100644 --- a/libc/test/src/sys/socket/linux/socketopt_test.cpp +++ b/libc/test/src/sys/socket/linux/socketopt_test.cpp @@ -11,13 +11,12 @@ #include "hdr/types/struct_linger.h" #include "hdr/types/struct_timespec.h" #include "hdr/types/struct_timeval.h" +#include "src/__support/time/clock_gettime.h" #include "src/sys/socket/getsockopt.h" #include "src/sys/socket/recv.h" #include "src/sys/socket/setsockopt.h" #include "src/sys/socket/socket.h" #include "src/sys/socket/socketpair.h" -#include "src/time/clock_gettime.h" - #include "src/unistd/close.h" #include "src/unistd/pipe.h" @@ -145,11 +144,13 @@ TEST_F(LlvmLibcSocketOptTest, ReceiveTimeout) { char buffer[10]; struct timespec start, end; - ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &start), 0); + ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &start) + .has_value()); // Read/recv on empty socket should block for ~1s and fail with EAGAIN. ASSERT_THAT(LIBC_NAMESPACE::recv(sv[0], buffer, sizeof(buffer), 0), Fails(EAGAIN)); - ASSERT_EQ(LIBC_NAMESPACE::clock_gettime(CLOCK_MONOTONIC, &end), 0); + ASSERT_TRUE(LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &end) + .has_value()); int64_t elapsed_seconds = end.tv_sec - start.tv_sec; int64_t elapsed_nseconds = end.tv_nsec - start.tv_nsec; From 931a00eca6db8eb5de674f27e1a7d2bde2d045d1 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 10 Jul 2026 12:32:54 +0200 Subject: [PATCH 112/125] offload: Match amdgpu triple name in lit config (#208551) The configured offload system target is now amdgpu-amd-amdhsa since d776ee4d4cae. --- offload/test/lit.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/offload/test/lit.cfg b/offload/test/lit.cfg index 03f3db08a2def..95f33caffdb6f 100644 --- a/offload/test/lit.cfg +++ b/offload/test/lit.cfg @@ -144,7 +144,7 @@ profdata_path = os.path.join(config.bin_llvm_tools_dir, "llvm-profdata") target = remove_suffix_if_present(config.libomptarget_current_target) has_profile_rt = True has_flang_rt = True -if target.startswith('amdgcn') or target.startswith('nvptx'): +if target.startswith('amdgpu') or target.startswith('nvptx'): has_profile_rt = bool(glob.glob(os.path.join( config.llvm_lib_directory, 'clang', '*', 'lib', target, 'libclang_rt.profile.a'))) @@ -171,7 +171,7 @@ if config.libomptarget_current_target.startswith('nvptx'): except ValueError: # If the architecture is invalid, assume it is supported. supports_unified_shared_memory = True -elif config.libomptarget_current_target.startswith('amdgcn'): +elif config.libomptarget_current_target.startswith('amdgpu'): # amdgpu_test_arch contains a list of AMD GPUs in the system # only check the first one assuming that we will run the test on it. if (config.amdgpu_test_arch.startswith("gfx90a") or @@ -231,7 +231,7 @@ host_targets = [ if config.libomptarget_current_target.startswith('nvptx'): config.available_features.add('gpu') config.available_features.add('nvidiagpu') -if config.libomptarget_current_target.startswith('amdgcn'): +if config.libomptarget_current_target.startswith('amdgpu'): config.available_features.add('gpu') config.available_features.add('amdgpu') config.environment['HSA_DISABLE_COREDUMP_ON_EXCEPTION'] = '1' From dfdc1c34ec8ffbabf066e94e7b9fa5ced847c1b0 Mon Sep 17 00:00:00 2001 From: Jacob Crawley Date: Fri, 10 Jul 2026 11:33:21 +0100 Subject: [PATCH 113/125] [LV] Handle swapped blend inputs in predicated partial reductions (#208013) Addressing case missed by #194859. Detect the reduction update by checking both incoming values to determine which is the single use incoming blend value, rather than the previous approach which always assumed this would be incoming value 0. --- .../Transforms/Vectorize/VPlanTransforms.cpp | 35 +++- .../AArch64/partial-reduce-with-predicate.ll | 161 +++++++++++++++--- 2 files changed, 167 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index 343ee02007966..b4f7a5f7359f7 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -6639,6 +6639,22 @@ struct VPPartialReductionChain { VPBlendRecipe *Blend = nullptr; }; +// Return the incoming index of the single-use value in the blend, which is +// expected to be the predicated reduction update. +static std::optional +getBlendReductionUpdateValueIdx(VPBlendRecipe *Blend) { + assert(Blend && !Blend->isNormalized() && + Blend->getNumIncomingValues() == 2 && + "Expected a non-normalized blend with two incoming values"); + bool FirstIncomingHasOneUse = Blend->getIncomingValue(0)->hasOneUse(); + + // Only the update value should have one use (the blend). The previous + // value should always have at least two uses, the blend and the reduction. + if (FirstIncomingHasOneUse == Blend->getIncomingValue(1)->hasOneUse()) + return std::nullopt; + return FirstIncomingHasOneUse ? 0 : 1; +} + static VPSingleDefRecipe * optimizeExtendsForPartialReduction(VPSingleDefRecipe *Op) { // reduce.add(mul(ext(A), C)) @@ -6836,7 +6852,12 @@ static void transformToPartialReduction(const VPPartialReductionChain &Chain, m_Specific(RdxPhi)))); if (Chain.Blend) { - VPValue *BlendCond = Chain.Blend->getMask(0); + std::optional BlendReductionIdx = + getBlendReductionUpdateValueIdx(Chain.Blend); + assert(BlendReductionIdx && + Chain.Blend->getIncomingValue(*BlendReductionIdx) == WidenRecipe && + "Expected blend to contain the reduction update"); + VPValue *BlendCond = Chain.Blend->getMask(*BlendReductionIdx); Cond = ExitValue ? VPBuilder(WidenRecipe) .createLogicalAnd(Cond, BlendCond, WidenRecipe->getDebugLoc()) @@ -7084,11 +7105,17 @@ getScaledReductions(VPReductionPHIRecipe *RedPhiR) { VPValue *CurrentValue = ExitValue; while (CurrentValue != RedPhiR) { VPBlendRecipe *Blend = dyn_cast(CurrentValue); + std::optional BlendReductionIdx; if (Blend) { assert(!Blend->isNormalized() && "Expect Blend not to be normalized."); - CurrentValue = Blend->getIncomingValue(0); - if (Blend->getNumIncomingValues() != 2 || !CurrentValue->hasOneUse()) + if (Blend->getNumIncomingValues() != 2) return std::nullopt; + + BlendReductionIdx = getBlendReductionUpdateValueIdx(Blend); + if (!BlendReductionIdx) + return std::nullopt; + + CurrentValue = Blend->getIncomingValue(*BlendReductionIdx); } auto *UpdateR = dyn_cast(CurrentValue); @@ -7112,7 +7139,7 @@ getScaledReductions(VPReductionPHIRecipe *RedPhiR) { // Look for VPBlend(reduce(PrevValue, Op), PrevValue), where // reduce is equal to CurrentValue. This can be lowered as // a conditional reduction by hoisting the select to the inputs. - if (Blend && Blend->getIncomingValue(1) != PrevValue) + if (Blend && Blend->getIncomingValue(1 - *BlendReductionIdx) != PrevValue) return std::nullopt; Type *ExtSrcType = ExtendedOp->ExtendA.SrcType; diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll index 1309a6bb268c3..6a73f63e41a2e 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/partial-reduce-with-predicate.ll @@ -72,14 +72,14 @@ define i32 @pred_reduction(ptr %src, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP7]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = xor i1 [[TMP9]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = xor i1 [[TMP8]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP11]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP10]] ; entry: br label %for.body @@ -177,14 +177,14 @@ define i32 @pred_reduction_sext(ptr %src, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP7]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = xor i1 [[TMP9]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = xor i1 [[TMP8]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP9]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP11]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP10]] ; entry: br label %for.body @@ -294,14 +294,14 @@ define i32 @pred_reduction_dotprod(ptr %a, ptr %b, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP10]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP13]] ; entry: br label %for.body @@ -416,12 +416,12 @@ define i32 @pred_sub_reduction(ptr %a, ptr %b, ptr %cond, i64 %N) #0 { ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP10]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP15:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) -; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP15]] +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = sub i32 0, [[TMP13]] ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: ; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] @@ -660,14 +660,14 @@ define i32 @reduction_before_pred(ptr %src, ptr noalias %src_b, ptr %cond, i64 % ; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE3]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[PARTIAL_REDUCE]], [[TMP9]]) ; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] ; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) -; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 -; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = xor i1 [[TMP11]], true -; CHECK-TAILFOLD-NEXT: br i1 [[TMP12]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]] +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = xor i1 [[TMP10]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP11]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]] ; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: -; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE3]]) +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE3]]) ; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] ; CHECK-TAILFOLD: [[EXIT]]: -; CHECK-TAILFOLD-NEXT: ret i32 [[TMP13]] +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP12]] ; entry: br label %for.body @@ -703,6 +703,117 @@ exit: ret i32 %sum.2 } +; Predicated reduction where the VPBlend has the previous accumulator +; as incoming value 0 and the reduction update as incoming value 1. +; Checks that the single use update value will be selected from either +; position rather than assuming it's always incoming value 0. +; Placing the update block (if.then) before for.body will ensure the +; update value comes second. +define i32 @pred_reduction_incoming_1(ptr %src, ptr %cond, i64 %N) #0 { +; CHECK-LABEL: define i32 @pred_reduction_incoming_1( +; CHECK-SAME: ptr [[SRC:%.*]], ptr [[COND:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i64 [[TMP0]], 5 +; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], [[TMP1]] +; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]] +; CHECK: [[VECTOR_PH]]: +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw i64 [[TMP0]], 4 +; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 1 +; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], [[TMP3]] +; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]] +; CHECK-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK: [[VECTOR_BODY]]: +; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[VEC_PHI1:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE6:%.*]], %[[VECTOR_BODY]] ] +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[COND]], i64 [[INDEX]] +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 [[TMP2]] +; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load , ptr [[TMP4]], align 1 +; CHECK-NEXT: [[WIDE_LOAD2:%.*]] = load , ptr [[TMP5]], align 1 +; CHECK-NEXT: [[TMP12:%.*]] = icmp ne [[WIDE_LOAD]], zeroinitializer +; CHECK-NEXT: [[TMP13:%.*]] = icmp ne [[WIDE_LOAD2]], zeroinitializer +; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[INDEX]] +; CHECK-NEXT: [[TMP15:%.*]] = getelementptr i8, ptr [[TMP14]], i64 [[TMP2]] +; CHECK-NEXT: [[WIDE_MASKED_LOAD4:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP14]], [[TMP12]], poison) +; CHECK-NEXT: [[WIDE_MASKED_LOAD5:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP15]], [[TMP13]], poison) +; CHECK-NEXT: [[TMP16:%.*]] = zext [[WIDE_MASKED_LOAD4]] to +; CHECK-NEXT: [[TMP17:%.*]] = select [[TMP12]], [[TMP16]], zeroinitializer +; CHECK-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP17]]) +; CHECK-NEXT: [[TMP18:%.*]] = zext [[WIDE_MASKED_LOAD5]] to +; CHECK-NEXT: [[TMP19:%.*]] = select [[TMP13]], [[TMP18]], zeroinitializer +; CHECK-NEXT: [[PARTIAL_REDUCE6]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI1]], [[TMP19]]) +; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]] +; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] +; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]] +; CHECK: [[MIDDLE_BLOCK]]: +; CHECK-NEXT: [[BIN_RDX:%.*]] = add [[PARTIAL_REDUCE6]], [[PARTIAL_REDUCE]] +; CHECK-NEXT: [[TMP21:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[BIN_RDX]]) +; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]] +; CHECK-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH]] +; CHECK: [[SCALAR_PH]]: +; +; CHECK-TAILFOLD-LABEL: define i32 @pred_reduction_incoming_1( +; CHECK-TAILFOLD-SAME: ptr [[SRC:%.*]], ptr [[COND:%.*]], i64 [[N:%.*]]) #[[ATTR0]] { +; CHECK-TAILFOLD-NEXT: [[ENTRY:.*:]] +; CHECK-TAILFOLD-NEXT: br label %[[VECTOR_PH:.*]] +; CHECK-TAILFOLD: [[VECTOR_PH]]: +; CHECK-TAILFOLD-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-TAILFOLD-NEXT: [[TMP1:%.*]] = shl nuw i64 [[TMP0]], 4 +; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 0, i64 [[N]]) +; CHECK-TAILFOLD-NEXT: br label %[[VECTOR_BODY:.*]] +; CHECK-TAILFOLD: [[VECTOR_BODY]]: +; CHECK-TAILFOLD-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[TMP4:%.*]] = phi [ [[ACTIVE_LANE_MASK_ENTRY]], %[[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[VEC_PHI:%.*]] = phi [ zeroinitializer, %[[VECTOR_PH]] ], [ [[PARTIAL_REDUCE:%.*]], %[[VECTOR_BODY]] ] +; CHECK-TAILFOLD-NEXT: [[TMP5:%.*]] = getelementptr inbounds nuw i8, ptr [[COND]], i64 [[INDEX]] +; CHECK-TAILFOLD-NEXT: [[WIDE_MASKED_LOAD1:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP5]], [[TMP4]], poison) +; CHECK-TAILFOLD-NEXT: [[TMP6:%.*]] = icmp ne [[WIDE_MASKED_LOAD1]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[TMP8:%.*]] = select [[TMP4]], [[TMP6]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[TMP9:%.*]] = getelementptr i8, ptr [[SRC]], i64 [[INDEX]] +; CHECK-TAILFOLD-NEXT: [[WIDE_MASKED_LOAD2:%.*]] = call @llvm.masked.load.nxv16i8.p0(ptr align 1 [[TMP9]], [[TMP8]], poison) +; CHECK-TAILFOLD-NEXT: [[TMP10:%.*]] = zext [[WIDE_MASKED_LOAD2]] to +; CHECK-TAILFOLD-NEXT: [[TMP11:%.*]] = select [[TMP8]], [[TMP10]], zeroinitializer +; CHECK-TAILFOLD-NEXT: [[PARTIAL_REDUCE]] = call @llvm.vector.partial.reduce.add.nxv4i32.nxv16i32( [[VEC_PHI]], [[TMP11]]) +; CHECK-TAILFOLD-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP1]] +; CHECK-TAILFOLD-NEXT: [[ACTIVE_LANE_MASK_NEXT]] = call @llvm.get.active.lane.mask.nxv16i1.i64(i64 [[INDEX_NEXT]], i64 [[N]]) +; CHECK-TAILFOLD-NEXT: [[TMP12:%.*]] = extractelement [[ACTIVE_LANE_MASK_NEXT]], i64 0 +; CHECK-TAILFOLD-NEXT: [[TMP13:%.*]] = xor i1 [[TMP12]], true +; CHECK-TAILFOLD-NEXT: br i1 [[TMP13]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK-TAILFOLD: [[MIDDLE_BLOCK]]: +; CHECK-TAILFOLD-NEXT: [[TMP14:%.*]] = call i32 @llvm.vector.reduce.add.nxv4i32( [[PARTIAL_REDUCE]]) +; CHECK-TAILFOLD-NEXT: br label %[[EXIT:.*]] +; CHECK-TAILFOLD: [[EXIT]]: +; CHECK-TAILFOLD-NEXT: ret i32 [[TMP14]] +; +entry: + br label %for.body + +if.then: + %arrayidx2 = getelementptr inbounds nuw i8, ptr %src, i64 %iv + %val = load i8, ptr %arrayidx2, align 1 + %conv = zext i8 %val to i32 + %add = add nsw i32 %sum, %conv + br label %for.inc + +for.body: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ] + %sum = phi i32 [ 0, %entry ], [ %sum.1, %for.inc ] + %arrayidx = getelementptr inbounds nuw i8, ptr %cond, i64 %iv + %c = load i8, ptr %arrayidx, align 1 + %tobool.not = icmp eq i8 %c, 0 + br i1 %tobool.not, label %for.inc, label %if.then + +for.inc: + %sum.1 = phi i32 [ %add, %if.then ], [ %sum, %for.body ] + %iv.next = add nuw nsw i64 %iv, 1 + %exitcond.not = icmp eq i64 %iv.next, %N + br i1 %exitcond.not, label %exit, label %for.body + +exit: + ret i32 %sum.1 +} + ; UTC_ARGS: --disable ; Negative test - expect not to generate a partial reduction as phi From 95cfe69f75b2080a528e582f269859ac10daade1 Mon Sep 17 00:00:00 2001 From: Iliyan Georgiev Date: Fri, 10 Jul 2026 11:38:50 +0100 Subject: [PATCH 114/125] [mlir][tosa] Fix reduce-transpose sub-byte handling (#208446) - Fix element size calculation when processing sub-byte types - Add tests for i1 and i4 Signed-off-by: Iliyan Georgiev --- .../Tosa/Transforms/TosaReduceTransposes.cpp | 3 +-- .../Dialect/Tosa/tosa-reduce-transposes.mlir | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp index 0bd415040f22f..ffd48e8ab16ae 100644 --- a/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp +++ b/mlir/lib/Dialect/Tosa/Transforms/TosaReduceTransposes.cpp @@ -233,8 +233,7 @@ TosaReduceTransposes::transposeDenseAttribute(DenseElementsAttr input, // perms: dim 0→2, dim 1→0, dim 2→1, giving source position // calculated as 1*inputStrides[2] + 1*inputStrides[0] + 2*inputStrides[1] // = 1*1 + 1*12 + 2*4 = 21 - - size_t elementSize = oldType.getElementTypeBitWidth() / 8; + size_t elementSize = llvm::divideCeil(oldType.getElementTypeBitWidth(), 8); int64_t numElements = oldType.getNumElements(); SmallVector outputBuffer(numElements * elementSize); diff --git a/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir b/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir index 0ad3068011f7f..46e4f504af0ec 100644 --- a/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir +++ b/mlir/test/Dialect/Tosa/tosa-reduce-transposes.mlir @@ -597,3 +597,21 @@ func.func @test_unimplemented_static_diverges_to_one_nullifying_one_non_nullifyi %result = tosa.transpose %add {perms = array}: (tensor<1x3x4x2xi32>) -> tensor<1x2x3x4xi32> return %result : tensor<1x2x3x4xi32> } + +// CHECK-LABEL: @test_transpose_bool +// CHECK: %{{.*}} = "tosa.const"() +// CHECK-SAME{LITERAL}: dense<[[true, false], [false, false], [false, true]]> +func.func @test_transpose_bool() -> tensor<3x2xi1> { + %0 = "tosa.const"() <{values = dense<[[true, false, false], [false, false, true]]> : tensor<2x3xi1>}> : () -> tensor<2x3xi1> + %1 = tosa.transpose %0 {perms = array} : (tensor<2x3xi1>) -> tensor<3x2xi1> + return %1 : tensor<3x2xi1> +} + +// CHECK-LABEL: @test_transpose_i4 +// CHECK: %{{.*}} = "tosa.const"() +// CHECK-SAME{LITERAL}: dense<[[1, 4], [2, 5], [3, 6]]> +func.func @test_transpose_i4() -> tensor<3x2xi4> { + %0 = "tosa.const"() <{values = dense<[[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi4>}> : () -> tensor<2x3xi4> + %1 = tosa.transpose %0 {perms = array} : (tensor<2x3xi4>) -> tensor<3x2xi4> + return %1 : tensor<3x2xi4> +} \ No newline at end of file From cd662a7c4fb03a88d0e429a7fc8d8b470a812e2b Mon Sep 17 00:00:00 2001 From: Michiel Derhaeg Date: Fri, 10 Jul 2026 12:38:53 +0200 Subject: [PATCH 115/125] [clang][scan-build-py] Fix configure scripts when using Python 3.14 (#206792) Python 3.14 (PEP 765) warns about return statements inside finally blocks. This warning breaks intercept-build and friends for configure scripts. The bare except already catches everything, so falling through to the return is equivalent and silences the SyntaxWarning. --- clang/tools/scan-build-py/lib/libscanbuild/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/tools/scan-build-py/lib/libscanbuild/__init__.py b/clang/tools/scan-build-py/lib/libscanbuild/__init__.py index ba1600866c4d7..b9ae777bfae73 100644 --- a/clang/tools/scan-build-py/lib/libscanbuild/__init__.py +++ b/clang/tools/scan-build-py/lib/libscanbuild/__init__.py @@ -196,9 +196,8 @@ def run_compiler(executable): function(result, call) except: logging.exception("Compiler wrapper failed complete.") - finally: - # Always return the real compiler exit code. - return result + # Always return the real compiler exit code. + return result def wrapper_environment(args): From 4a5bdadabdfba0f38188adc1e68210d3375b7f95 Mon Sep 17 00:00:00 2001 From: lianjinfeng2003 <101249452+mygitljf@users.noreply.github.com> Date: Fri, 10 Jul 2026 18:40:55 +0800 Subject: [PATCH 116/125] [mlir] Fix RDV poison cleanup (#206270) I moved the poison replacement step before cleanup paths that can drop uses and leave queued operands temporarily null. This keeps region branch operands valid while the later cleanup removes dead arguments and results. Fixes #206094 --- mlir/lib/Transforms/RemoveDeadValues.cpp | 67 ++++++++++++-------- mlir/test/Transforms/remove-dead-values.mlir | 27 ++++++++ 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp index 812ae50d89ed1..6e55bc390be23 100644 --- a/mlir/lib/Transforms/RemoveDeadValues.cpp +++ b/mlir/lib/Transforms/RemoveDeadValues.cpp @@ -516,15 +516,12 @@ static void processBranchOp(BranchOpInterface branchOp, RunLivenessAnalysis &la, } } -/// Create ub.poison ops for the given values. If a value has no uses, return -/// an "empty" value. -static SmallVector createPoisonedValues(OpBuilder &b, - ValueRange values) { - return llvm::map_to_vector(values, [&](Value value) { - if (value.use_empty()) - return Value(); - return ub::PoisonOp::create(b, value.getLoc(), value.getType()).getResult(); - }); +/// Create a ub.poison op for the given value. If it has no uses, return an +/// "empty" value. +static Value createPoisonedValue(OpBuilder &b, Value value) { + if (value.use_empty()) + return Value(); + return ub::PoisonOp::create(b, value.getLoc(), value.getType()).getResult(); } namespace { @@ -554,7 +551,30 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { TrackingListener listener; IRRewriter rewriter(ctx, &listener); - // 1. Blocks, We must remove the block arguments and successor operands before + // 1. Operands to replace with poison. These rewrites need the original + // operand values for their location and type, so they must run before any + // cleanup that can drop uses and leave operands temporarily null. + LDBG() << "Replacing dead operands with poison in " << list.operands.size() + << " operand lists"; + for (OperandsToCleanup &o : list.operands) { + if (!o.replaceWithPoison || !o.nonLive.any()) + continue; + LDBG_OS([&](raw_ostream &os) { + os << "Replacing non-live operands ["; + llvm::interleaveComma(o.nonLive.set_bits(), os); + os << "] with poison in operation: " + << OpWithFlags(o.op, + OpPrintingFlags().skipRegions().printGenericOpForm()); + }); + rewriter.setInsertionPoint(o.op); + for (auto deadIdx : o.nonLive.set_bits()) { + Value operand = o.op->getOperand(deadIdx); + assert(operand && "expected non-null operand for poison replacement"); + o.op->setOperand(deadIdx, createPoisonedValue(rewriter, operand)); + } + } + + // 2. Blocks, We must remove the block arguments and successor operands before // deleting the operation, as they may reside in the region operation. LDBG() << "Cleaning up " << list.blocks.size() << " block argument lists"; for (auto &b : list.blocks) { @@ -579,7 +599,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { } } - // 2. Successor Operands + // 3. Successor Operands LDBG() << "Cleaning up " << list.successorOperands.size() << " successor operand lists"; for (auto &op : list.successorOperands) { @@ -603,7 +623,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { } } - // 3. Functions + // 4. Functions LDBG() << "Cleaning up " << list.functions.size() << " functions"; // Record which function arguments were erased so we can shrink call-site // argument segments for CallOpInterface operations (e.g. ops using @@ -637,9 +657,11 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { (void)f.funcOp.eraseResults(f.nonLiveRets); } - // 4. Operands + // 5. Operands LDBG() << "Cleaning up " << list.operands.size() << " operand lists"; for (OperandsToCleanup &o : list.operands) { + if (o.replaceWithPoison) + continue; // Handle call-specific cleanup only when we have a cached callee reference. // This avoids expensive symbol lookup and is defensive against future // changes. @@ -682,20 +704,11 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { << OpWithFlags(o.op, OpPrintingFlags().skipRegions().printGenericOpForm()); }); - if (o.replaceWithPoison) { - rewriter.setInsertionPoint(o.op); - for (auto deadIdx : o.nonLive.set_bits()) { - o.op->setOperand( - deadIdx, createPoisonedValues(rewriter, o.op->getOperand(deadIdx)) - .front()); - } - } else { - o.op->eraseOperands(o.nonLive); - } + o.op->eraseOperands(o.nonLive); } } - // 5. Results + // 6. Results LDBG() << "Cleaning up " << list.results.size() << " result lists"; for (auto &r : list.results) { LDBG_OS([&](raw_ostream &os) { @@ -708,7 +721,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { dropUsesAndEraseResults(rewriter, r.op, r.nonLive); } - // 6. Operations + // 7. Operations LDBG() << "Cleaning up " << list.operations.size() << " operations"; for (Operation *op : list.operations) { LDBG() << "Erasing operation: " @@ -737,7 +750,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { continue; rewriter.setInsertionPoint(op); - Value poisonedValue = createPoisonedValues(rewriter, opResult).front(); + Value poisonedValue = createPoisonedValue(rewriter, opResult); rewriter.replaceAllUsesWith(opResult, poisonedValue); } @@ -745,7 +758,7 @@ static void cleanUpDeadVals(MLIRContext *ctx, RDVFinalCleanupList &list) { rewriter.eraseOp(op); } - // 7. Remove all dead poison ops. + // 8. Remove all dead poison ops. for (ub::PoisonOp poisonOp : listener.poisonOps) { if (poisonOp.use_empty()) poisonOp.erase(); diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir index 64088ce15cd48..390a448060b7f 100644 --- a/mlir/test/Transforms/remove-dead-values.mlir +++ b/mlir/test/Transforms/remove-dead-values.mlir @@ -624,6 +624,33 @@ module @return_void_with_unused_argument { // ----- +// CHECK-LABEL: func.func private @keep_region_branch_operands_valid() { +func.func private @keep_region_branch_operands_valid(%arg0: memref) { + %false = arith.constant false + %cst = arith.constant 2.000000e+00 : f64 + %0 = memref.load %arg0[] {name = "caller"} : memref + memref.store %cst, %arg0[] {name = "callee"} : memref + // CHECK: %[[COND:.*]] = ub.poison : i1 + // CHECK: scf.if %[[COND]] + // CHECK: %[[YIELD0:.*]] = ub.poison : memref + // CHECK: scf.yield %[[YIELD0]] : memref + // CHECK: %[[YIELD1:.*]] = ub.poison : memref + // CHECK: scf.yield %[[YIELD1]] : memref + %1 = scf.if %false -> (memref) { + scf.yield %arg0 : memref + } else { + %2 = bufferization.clone %arg0 : memref to memref + scf.yield %2 : memref + } + %true = arith.constant true + %base_buffer, %offset = memref.extract_strided_metadata %arg0 : memref -> memref, index + %base_buffer_0, %offset_1 = memref.extract_strided_metadata %1 : memref -> memref, index + bufferization.dealloc (%base_buffer, %base_buffer_0 : memref, memref) if (%false, %true) + return +} + +// ----- + // CHECK-LABEL: module @dynamically_unreachable module @dynamically_unreachable { func.func @dynamically_unreachable() { From ec3bda3b5ec56268c17ded81eb5307278da16b60 Mon Sep 17 00:00:00 2001 From: Matthew Devereau Date: Fri, 10 Jul 2026 11:44:18 +0100 Subject: [PATCH 117/125] [AArch64][InstCombine] Fold zext of all-active SVE cmpne-zero (#207720) Fold zext(cmpne(ptrue, x, 0)) to umin(ptrue, x, 1). Do not fold non-ptrue predicates, since cmpne zeros inactive lanes and umin merges inactive lanes --- .../AArch64/AArch64TargetTransformInfo.cpp | 29 +++++++ .../AArch64/sve-intrinsic-opts-cmpne.ll | 82 +++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp index caca744fd4303..9e1a0960617a5 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -2179,6 +2179,32 @@ static std::optional instCombineXorSVECmpCC(InstCombiner &IC, return &II; } +// zext(cmpne(ptrue, %v, 0)) +// -> umin(%pg, %v, 1) +static std::optional instCombineZExtSVECmpNE(InstCombiner &IC, + IntrinsicInst &II) { + if (!isAllActivePredicate(II.getOperand(0)) || + !match(II.getOperand(2), m_Zero())) + return std::nullopt; + + for (auto *U : II.users()) { + if (match(U, m_ZExt(m_Specific(&II)))) { + auto *User = cast(U); + Type *Ty = II.getOperand(1)->getType(); + if (User->getType() != Ty) + continue; + IC.Builder.SetInsertPoint(User); + Value *UMin = IC.Builder.CreateIntrinsic( + Intrinsic::aarch64_sve_umin, Ty, + {II.getOperand(0), II.getOperand(1), ConstantInt::get(Ty, 1)}); + IC.replaceInstUsesWith(*User, UMin); + IC.eraseInstFromFunction(*User); + return &II; + } + } + return std::nullopt; +} + static std::optional instCombineSVECmpNE(InstCombiner &IC, IntrinsicInst &II) { LLVMContext &Ctx = II.getContext(); @@ -2186,6 +2212,9 @@ static std::optional instCombineSVECmpNE(InstCombiner &IC, if (auto Res = instCombineXorSVECmpCC(IC, II)) return Res; + if (auto Res = instCombineZExtSVECmpNE(IC, II)) + return Res; + if (!isAllActivePredicate(II.getArgOperand(0))) return std::nullopt; diff --git a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll index e803572a06523..11e6e0089293a 100644 --- a/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll +++ b/llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-opts-cmpne.ll @@ -261,6 +261,88 @@ define @not_cmpne_wrong_xor_operand( %vec_a ret %not } +define @zext_cmpne_i8( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_i8( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_zero_lhs_i8( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_zero_lhs_i8( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[TMP1:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), zeroinitializer, [[VEC]]) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[TMP1]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), zeroinitializer, %vec) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_wide_i32( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_wide_i32( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv4i32( splat (i1 true), [[VEC]], splat (i32 1)) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.wide.nxv4i32( splat (i1 true), %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_non_ptrue( %vec, %pg) #0 { +; CHECK-LABEL: define @zext_cmpne_non_ptrue( +; CHECK-SAME: [[VEC:%.*]], [[PG:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( [[PG]], [[VEC]], zeroinitializer) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[CMP]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( %pg, %vec, zeroinitializer) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_nonzero_rhs( %vec) #0 { +; CHECK-LABEL: define @zext_cmpne_nonzero_rhs( +; CHECK-SAME: [[VEC:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: [[ZEXT:%.*]] = zext [[CMP]] to +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, splat (i8 1)) + %zext = zext %cmp to + ret %zext +} + +define @zext_cmpne_multiple_uses( %vec, %pg) #0 { +; CHECK-LABEL: define @zext_cmpne_multiple_uses( +; CHECK-SAME: [[VEC:%.*]], [[PG:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[CMP:%.*]] = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), [[VEC]], zeroinitializer) +; CHECK-NEXT: [[AND_1:%.*]] = and [[CMP]], [[PG]] +; CHECK-NEXT: call void (...) @llvm.fake.use( [[AND_1]]) +; CHECK-NEXT: [[ZEXT:%.*]] = call @llvm.aarch64.sve.umin.u.nxv16i8( splat (i1 true), [[VEC]], splat (i8 1)) +; CHECK-NEXT: [[ZEXT_1:%.*]] = zext [[CMP]] to +; CHECK-NEXT: call void (...) @llvm.fake.use( [[ZEXT_1]]) +; CHECK-NEXT: ret [[ZEXT]] +; + %cmp = call @llvm.aarch64.sve.cmpne.nxv16i8( splat (i1 true), %vec, zeroinitializer) + + %and.1 = and %cmp, %pg + call void (...) @llvm.fake.use( %and.1) + + %zext.0 = zext %cmp to + + %zext.1 = zext %cmp to + call void (...) @llvm.fake.use( %zext.1) + + ret %zext.0 +} + ; Cases that cannot be converted define @dupq_neg1() #0 { From 9dad160b3b26e8ba2698f0ab695630444b2760fb Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Fri, 10 Jul 2026 11:47:25 +0100 Subject: [PATCH 118/125] [VPlan] Relax type of DerivedIV start value (NFC) (#206464) Change it from VPIRValue -> VPValue, as several usecases require it, while adding a check in the verifier. --- .../Vectorize/LoopVectorizationPlanner.h | 2 +- llvm/lib/Transforms/Vectorize/VPlan.h | 6 ++-- .../Transforms/Vectorize/VPlanTransforms.cpp | 2 +- .../Transforms/Vectorize/VPlanVerifier.cpp | 7 +++++ .../Vectorize/VPlanVerifierTest.cpp | 30 ++++++++++++++++++- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h index e4cfdecfb1acf..cd02ced2942d1 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h +++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationPlanner.h @@ -406,7 +406,7 @@ class VPBuilder { /// induction with \p Start and \p Step values, using \p Start + \p Current * /// \p Step. VPDerivedIVRecipe *createDerivedIV(InductionDescriptor::InductionKind Kind, - FPMathOperator *FPBinOp, VPIRValue *Start, + FPMathOperator *FPBinOp, VPValue *Start, VPValue *Current, VPValue *Step) { return tryInsertInstruction( new VPDerivedIVRecipe(Kind, FPBinOp, Start, Current, Step)); diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index eefe02b3e41ad..1ce5786793c49 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -4181,8 +4181,8 @@ class VPDerivedIVRecipe : public VPSingleDefRecipe { public: VPDerivedIVRecipe(InductionDescriptor::InductionKind Kind, - const FPMathOperator *FPBinOp, VPIRValue *Start, - VPValue *IV, VPValue *Step) + const FPMathOperator *FPBinOp, VPValue *Start, VPValue *IV, + VPValue *Step) : VPSingleDefRecipe(VPRecipeBase::VPDerivedIVSC, {Start, IV, Step}, Start->getScalarType(), nullptr), Kind(Kind), FPBinOp(FPBinOp) {} @@ -4204,7 +4204,7 @@ class VPDerivedIVRecipe : public VPSingleDefRecipe { InstructionCost computeCost(ElementCount VF, VPCostContext &Ctx) const override; - VPIRValue *getStartValue() const { return cast(getOperand(0)); } + VPValue *getStartValue() const { return getOperand(0); } VPValue *getIndex() const { return getOperand(1); } VPValue *getStepValue() const { return getOperand(2); } const FPMathOperator *getFPBinOp() const { return FPBinOp; } diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp index b4f7a5f7359f7..1185b748599d1 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -4086,7 +4086,7 @@ static void expandVPWidenPointerInduction(VPWidenPointerInductionRecipe *R) { /// Expand a VPDerivedIVRecipe into executable recipes. static void expandVPDerivedIV(VPDerivedIVRecipe *R) { VPBuilder Builder(R); - VPIRValue *Start = R->getStartValue(); + VPValue *Start = R->getStartValue(); VPValue *Step = R->getStepValue(); VPValue *Index = R->getIndex(); Type *StepTy = Step->getScalarType(); diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 656a5f25878df..a4d6cc0ecb480 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -334,6 +334,13 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { break; } } + if (const auto *DIV = dyn_cast(&R)) { + if (!DIV->getStartValue()->isDefinedOutsideLoopRegions()) { + errs() << "VPDerivedIVRecipe must have start value defined outside " + "loop regions\n"; + return false; + } + } if (const auto *ScalarIVSteps = dyn_cast(&R)) { unsigned NumOps = ScalarIVSteps->getNumOperands(); if (NumOps != 3 && NumOps != 4) { diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp index 64101278c08bf..ebf7a0942ae2c 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "../lib/Transforms/Vectorize/VPlanVerifier.h" +#include "../lib/Transforms/Vectorize/LoopVectorizationPlanner.h" #include "../lib/Transforms/Vectorize/VPlan.h" -#include "../lib/Transforms/Vectorize/VPlanCFG.h" #include "VPlanTestBase.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -330,6 +330,34 @@ TEST_F(VPVerifierTest, NonHeaderPHIInHeader) { delete PHINode; } +TEST_F(VPVerifierTest, DerivedIVWithStartInLoopRegions) { + VPlan &Plan = getPlan(); + auto *I32Ty = Type::getInt32Ty(C); + VPBasicBlock *Entry = Plan.getEntry(); + VPBasicBlock *Latch = Plan.createVPBasicBlock("latch"); + + VPBuilder Builder(Latch); + VPValue *Start = Builder.createNot(Plan.getPoison(I32Ty)); + Builder.createDerivedIV(InductionDescriptor::IK_IntInduction, nullptr, Start, + Plan.getPoison(I32Ty), Plan.getPoison(I32Ty)); + Builder.createNaryOp(VPInstruction::BranchOnCond, Plan.getTrue()); + + VPRegionBlock *LoopR = Plan.createLoopRegion(I32Ty, DebugLoc::getUnknown(), + "loop", Latch, Latch); + VPBlockUtils::connectBlocks(Entry, LoopR); + VPBlockUtils::connectBlocks(LoopR, Plan.getScalarHeader()); + +#if GTEST_HAS_STREAM_REDIRECTION + ::testing::internal::CaptureStderr(); +#endif + EXPECT_FALSE(verifyVPlanIsValid(Plan)); +#if GTEST_HAS_STREAM_REDIRECTION + EXPECT_STREQ( + "VPDerivedIVRecipe must have start value defined outside loop regions\n", + ::testing::internal::GetCapturedStderr().c_str()); +#endif +} + TEST_F(VPVerifierTest, testRUN_VPLAN_PASS) { VPlan &Plan = getPlan(); VPIRValue *Zero = Plan.getConstantInt(32, 0); From e4798e75ccbc6f09e5b588713e82edc224f4b22a Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Fri, 10 Jul 2026 12:51:39 +0200 Subject: [PATCH 119/125] [clang][bytecode] Don't diagnose definition without body (#208679) Let the declared_at note point to the declaration in that case. --- clang/lib/AST/ByteCode/Interp.cpp | 6 ++++-- clang/test/AST/ByteCode/invalid.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index b2af27fc88542..0adcdfe6e78c9 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1110,8 +1110,10 @@ static bool diagnoseCallableDecl(InterpState &S, CodePtr OpPC, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; - if (DiagDecl->getDefinition()) - S.Note(DiagDecl->getDefinition()->getLocation(), diag::note_declared_at); + const FunctionDecl *Definition; + const Stmt *Body = DiagDecl->getBody(Definition); + if (Body && Definition) + S.Note(Definition->getLocation(), diag::note_declared_at); else S.Note(DiagDecl->getLocation(), diag::note_declared_at); } diff --git a/clang/test/AST/ByteCode/invalid.cpp b/clang/test/AST/ByteCode/invalid.cpp index e79b698a32719..930565181b202 100644 --- a/clang/test/AST/ByteCode/invalid.cpp +++ b/clang/test/AST/ByteCode/invalid.cpp @@ -218,3 +218,12 @@ namespace InvalidVirtualCast { static_assert((X *)(Y *)&z, ""); // both-error {{not an integral constant expression}} \ // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}} } + +namespace DefinitionInBody { + int foo(); // both-note {{declared here}} + int foo() { + static_assert(foo() == 1); // both-error {{not an integral constant expression}} \ + // both-note {{non-constexpr function 'foo' cannot be used in a constant expression}} + return 5; + } +} From 15df0ca2f9c8854dc0985f557b00a38b2d0af137 Mon Sep 17 00:00:00 2001 From: L-roro <115032777+L-roro@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:57:10 +0200 Subject: [PATCH 120/125] [Hexagon] Use word splats for repeated HVX build-vector words (#204808) buildHvxVectorReg packs small element vectors into i32 words before using the most frequent word to initialize the HVX vector. For i8/i16 result vectors, the old lowering created SPLAT_VECTOR with the final vector type, which selected a byte or halfword splat and broadcast only the low part of the packed word. The idea is to build the splat as a vector of i32 words first, then bitcast back to the final vector type. This preserves the full packed word while keeping normal byte and halfword scalar splat lowering unchanged. The test covers packed-word i8 and i16 cases, and also checks that true i8/i16 scalar splats still lower to byte/halfword splats. After testing with the SDK simulator, it looks to me like a larger 16-byte repeated-pattern case is still miscompiled after this change. It appears to be a broader issue in this build-vector construction path, so maybe this should be addressed in a different way that could fix all cases and not only these specific ones. Please let me know what you think. I have used AI for this proposal. The bug was originally found after running llvm-reduce on a large ll that had a completely unrelated bug. Co-authored-by: L-roro --- .../Target/Hexagon/HexagonISelLoweringHVX.cpp | 8 +- .../autohvx/isel-build-vector-splat-word.ll | 256 ++++++++++++++++++ 2 files changed, 263 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll diff --git a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp index fca33480265ad..b36c0b4e2faaf 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelLoweringHVX.cpp @@ -1077,7 +1077,13 @@ HexagonTargetLowering::buildHvxVectorReg(ArrayRef Values, SDValue HalfV = getZero(dl, VecTy, DAG); if (VecHist[n] > 1) { - SDValue SplatV = DAG.getNode(ISD::SPLAT_VECTOR, dl, VecTy, Words[n]); + // Always splat at word (i32) granularity so that the SPLAT_VECTOR node + // is selected as PS_vsplatrw (word broadcast) rather than PS_vsplatrb + // (byte broadcast of the low byte only), which would corrupt multi-byte + // element types. + MVT WordVecTy = MVT::getVectorVT(MVT::i32, HwLen / 4); + SDValue WordSplat = DAG.getNode(ISD::SPLAT_VECTOR, dl, WordVecTy, Words[n]); + SDValue SplatV = DAG.getBitcast(VecTy, WordSplat); HalfV = DAG.getNode(HexagonISD::VALIGN, dl, VecTy, {HalfV, SplatV, DAG.getConstant(HwLen/2, dl, MVT::i32)}); } diff --git a/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll b/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll new file mode 100644 index 0000000000000..bc3ffd688cdd9 --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/autohvx/isel-build-vector-splat-word.ll @@ -0,0 +1,256 @@ +; RUN: llc -mtriple=hexagon < %s | FileCheck %s + +target triple = "hexagon" + +; buildHvxVectorReg packs i8 elements into i32 words before initializing +; an HVX vector from the most frequent word. That initialization must +; use a word splat even though the final vector type is i8; a byte +; splat would broadcast only the low byte of %x. +define void @splat_i32_word_into_i8_vector(ptr %out, i32 %x, i8 %y) #0 { +; CHECK-LABEL: splat_i32_word_into_i8_vector: +; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}}) +; CHECK-NOT: .b = vsplat +; CHECK: vmem +entry: + %x0 = trunc i32 %x to i8 + %s1 = lshr i32 %x, 8 + %x1 = trunc i32 %s1 to i8 + %s2 = lshr i32 %x, 16 + %x2 = trunc i32 %s2 to i8 + %s3 = lshr i32 %x, 24 + %x3 = trunc i32 %s3 to i8 + + %v000 = insertelement <128 x i8> poison, i8 %x0, i32 0 + %v001 = insertelement <128 x i8> %v000, i8 %x1, i32 1 + %v002 = insertelement <128 x i8> %v001, i8 %x2, i32 2 + %v003 = insertelement <128 x i8> %v002, i8 %x3, i32 3 + %v004 = insertelement <128 x i8> %v003, i8 %x0, i32 4 + %v005 = insertelement <128 x i8> %v004, i8 %x1, i32 5 + %v006 = insertelement <128 x i8> %v005, i8 %x2, i32 6 + %v007 = insertelement <128 x i8> %v006, i8 %x3, i32 7 + %v008 = insertelement <128 x i8> %v007, i8 %x0, i32 8 + %v009 = insertelement <128 x i8> %v008, i8 %x1, i32 9 + %v010 = insertelement <128 x i8> %v009, i8 %x2, i32 10 + %v011 = insertelement <128 x i8> %v010, i8 %x3, i32 11 + %v012 = insertelement <128 x i8> %v011, i8 %x0, i32 12 + %v013 = insertelement <128 x i8> %v012, i8 %x1, i32 13 + %v014 = insertelement <128 x i8> %v013, i8 %x2, i32 14 + %v015 = insertelement <128 x i8> %v014, i8 %x3, i32 15 + %v016 = insertelement <128 x i8> %v015, i8 %x0, i32 16 + %v017 = insertelement <128 x i8> %v016, i8 %x1, i32 17 + %v018 = insertelement <128 x i8> %v017, i8 %x2, i32 18 + %v019 = insertelement <128 x i8> %v018, i8 %x3, i32 19 + %v020 = insertelement <128 x i8> %v019, i8 %x0, i32 20 + %v021 = insertelement <128 x i8> %v020, i8 %x1, i32 21 + %v022 = insertelement <128 x i8> %v021, i8 %x2, i32 22 + %v023 = insertelement <128 x i8> %v022, i8 %x3, i32 23 + %v024 = insertelement <128 x i8> %v023, i8 %x0, i32 24 + %v025 = insertelement <128 x i8> %v024, i8 %x1, i32 25 + %v026 = insertelement <128 x i8> %v025, i8 %x2, i32 26 + %v027 = insertelement <128 x i8> %v026, i8 %x3, i32 27 + %v028 = insertelement <128 x i8> %v027, i8 %x0, i32 28 + %v029 = insertelement <128 x i8> %v028, i8 %x1, i32 29 + %v030 = insertelement <128 x i8> %v029, i8 %x2, i32 30 + %v031 = insertelement <128 x i8> %v030, i8 %x3, i32 31 + %v032 = insertelement <128 x i8> %v031, i8 %x0, i32 32 + %v033 = insertelement <128 x i8> %v032, i8 %x1, i32 33 + %v034 = insertelement <128 x i8> %v033, i8 %x2, i32 34 + %v035 = insertelement <128 x i8> %v034, i8 %x3, i32 35 + %v036 = insertelement <128 x i8> %v035, i8 %x0, i32 36 + %v037 = insertelement <128 x i8> %v036, i8 %x1, i32 37 + %v038 = insertelement <128 x i8> %v037, i8 %x2, i32 38 + %v039 = insertelement <128 x i8> %v038, i8 %x3, i32 39 + %v040 = insertelement <128 x i8> %v039, i8 %x0, i32 40 + %v041 = insertelement <128 x i8> %v040, i8 %x1, i32 41 + %v042 = insertelement <128 x i8> %v041, i8 %x2, i32 42 + %v043 = insertelement <128 x i8> %v042, i8 %x3, i32 43 + %v044 = insertelement <128 x i8> %v043, i8 %x0, i32 44 + %v045 = insertelement <128 x i8> %v044, i8 %x1, i32 45 + %v046 = insertelement <128 x i8> %v045, i8 %x2, i32 46 + %v047 = insertelement <128 x i8> %v046, i8 %x3, i32 47 + %v048 = insertelement <128 x i8> %v047, i8 %x0, i32 48 + %v049 = insertelement <128 x i8> %v048, i8 %x1, i32 49 + %v050 = insertelement <128 x i8> %v049, i8 %x2, i32 50 + %v051 = insertelement <128 x i8> %v050, i8 %x3, i32 51 + %v052 = insertelement <128 x i8> %v051, i8 %x0, i32 52 + %v053 = insertelement <128 x i8> %v052, i8 %x1, i32 53 + %v054 = insertelement <128 x i8> %v053, i8 %x2, i32 54 + %v055 = insertelement <128 x i8> %v054, i8 %x3, i32 55 + %v056 = insertelement <128 x i8> %v055, i8 %x0, i32 56 + %v057 = insertelement <128 x i8> %v056, i8 %x1, i32 57 + %v058 = insertelement <128 x i8> %v057, i8 %x2, i32 58 + %v059 = insertelement <128 x i8> %v058, i8 %x3, i32 59 + %v060 = insertelement <128 x i8> %v059, i8 %x0, i32 60 + %v061 = insertelement <128 x i8> %v060, i8 %x1, i32 61 + %v062 = insertelement <128 x i8> %v061, i8 %x2, i32 62 + %v063 = insertelement <128 x i8> %v062, i8 %x3, i32 63 + %v064 = insertelement <128 x i8> %v063, i8 %y, i32 64 + %v065 = insertelement <128 x i8> %v064, i8 %x1, i32 65 + %v066 = insertelement <128 x i8> %v065, i8 %x2, i32 66 + %v067 = insertelement <128 x i8> %v066, i8 %x3, i32 67 + %v068 = insertelement <128 x i8> %v067, i8 %x0, i32 68 + %v069 = insertelement <128 x i8> %v068, i8 %y, i32 69 + %v070 = insertelement <128 x i8> %v069, i8 %x2, i32 70 + %v071 = insertelement <128 x i8> %v070, i8 %x3, i32 71 + %v072 = insertelement <128 x i8> %v071, i8 %x0, i32 72 + %v073 = insertelement <128 x i8> %v072, i8 %x1, i32 73 + %v074 = insertelement <128 x i8> %v073, i8 %y, i32 74 + %v075 = insertelement <128 x i8> %v074, i8 %x3, i32 75 + %v076 = insertelement <128 x i8> %v075, i8 %x0, i32 76 + %v077 = insertelement <128 x i8> %v076, i8 %x1, i32 77 + %v078 = insertelement <128 x i8> %v077, i8 %x2, i32 78 + %v079 = insertelement <128 x i8> %v078, i8 %y, i32 79 + %v080 = insertelement <128 x i8> %v079, i8 %x0, i32 80 + %v081 = insertelement <128 x i8> %v080, i8 %x1, i32 81 + %v082 = insertelement <128 x i8> %v081, i8 %x2, i32 82 + %v083 = insertelement <128 x i8> %v082, i8 %x3, i32 83 + %v084 = insertelement <128 x i8> %v083, i8 %x0, i32 84 + %v085 = insertelement <128 x i8> %v084, i8 %x1, i32 85 + %v086 = insertelement <128 x i8> %v085, i8 %x2, i32 86 + %v087 = insertelement <128 x i8> %v086, i8 %x3, i32 87 + %v088 = insertelement <128 x i8> %v087, i8 %x0, i32 88 + %v089 = insertelement <128 x i8> %v088, i8 %x1, i32 89 + %v090 = insertelement <128 x i8> %v089, i8 %x2, i32 90 + %v091 = insertelement <128 x i8> %v090, i8 %x3, i32 91 + %v092 = insertelement <128 x i8> %v091, i8 %x0, i32 92 + %v093 = insertelement <128 x i8> %v092, i8 %x1, i32 93 + %v094 = insertelement <128 x i8> %v093, i8 %x2, i32 94 + %v095 = insertelement <128 x i8> %v094, i8 %x3, i32 95 + %v096 = insertelement <128 x i8> %v095, i8 %x0, i32 96 + %v097 = insertelement <128 x i8> %v096, i8 %x1, i32 97 + %v098 = insertelement <128 x i8> %v097, i8 %x2, i32 98 + %v099 = insertelement <128 x i8> %v098, i8 %x3, i32 99 + %v100 = insertelement <128 x i8> %v099, i8 %x0, i32 100 + %v101 = insertelement <128 x i8> %v100, i8 %x1, i32 101 + %v102 = insertelement <128 x i8> %v101, i8 %x2, i32 102 + %v103 = insertelement <128 x i8> %v102, i8 %x3, i32 103 + %v104 = insertelement <128 x i8> %v103, i8 %x0, i32 104 + %v105 = insertelement <128 x i8> %v104, i8 %x1, i32 105 + %v106 = insertelement <128 x i8> %v105, i8 %x2, i32 106 + %v107 = insertelement <128 x i8> %v106, i8 %x3, i32 107 + %v108 = insertelement <128 x i8> %v107, i8 %x0, i32 108 + %v109 = insertelement <128 x i8> %v108, i8 %x1, i32 109 + %v110 = insertelement <128 x i8> %v109, i8 %x2, i32 110 + %v111 = insertelement <128 x i8> %v110, i8 %x3, i32 111 + %v112 = insertelement <128 x i8> %v111, i8 %x0, i32 112 + %v113 = insertelement <128 x i8> %v112, i8 %x1, i32 113 + %v114 = insertelement <128 x i8> %v113, i8 %x2, i32 114 + %v115 = insertelement <128 x i8> %v114, i8 %x3, i32 115 + %v116 = insertelement <128 x i8> %v115, i8 %x0, i32 116 + %v117 = insertelement <128 x i8> %v116, i8 %x1, i32 117 + %v118 = insertelement <128 x i8> %v117, i8 %x2, i32 118 + %v119 = insertelement <128 x i8> %v118, i8 %x3, i32 119 + %v120 = insertelement <128 x i8> %v119, i8 %x0, i32 120 + %v121 = insertelement <128 x i8> %v120, i8 %x1, i32 121 + %v122 = insertelement <128 x i8> %v121, i8 %x2, i32 122 + %v123 = insertelement <128 x i8> %v122, i8 %x3, i32 123 + %v124 = insertelement <128 x i8> %v123, i8 %x0, i32 124 + %v125 = insertelement <128 x i8> %v124, i8 %x1, i32 125 + %v126 = insertelement <128 x i8> %v125, i8 %x2, i32 126 + %v127 = insertelement <128 x i8> %v126, i8 %x3, i32 127 + store <128 x i8> %v127, ptr %out, align 128 + ret void +} + +define void @splat_i8_into_i8_vector(ptr %out, i8 %x) #0 { +; CHECK-LABEL: splat_i8_into_i8_vector: +; CHECK: v{{[0-9]+}}.b = vsplat(r{{[0-9]+}}) +; CHECK: vmem +entry: + %v0 = insertelement <128 x i8> poison, i8 %x, i32 0 + %v1 = shufflevector <128 x i8> %v0, <128 x i8> poison, <128 x i32> zeroinitializer + store <128 x i8> %v1, ptr %out, align 128 + ret void +} + +; The same word-splat requirement applies when the final vector type is +; i16 and the repeated value is a packed i32 containing two halfwords. +define void @splat_i32_word_into_i16_vector(ptr %out, i32 %x, i16 %y) #0 { +; CHECK-LABEL: splat_i32_word_into_i16_vector: +; CHECK: v{{[0-9]+}} = vsplat(r{{[0-9]+}}) +; CHECK-NOT: .h = vsplat +; CHECK: vmem +entry: + %x0 = trunc i32 %x to i16 + %s1 = lshr i32 %x, 16 + %x1 = trunc i32 %s1 to i16 + %v0 = insertelement <64 x i16> poison, i16 %x0, i32 0 + %v1 = insertelement <64 x i16> %v0, i16 %x1, i32 1 + %v2 = insertelement <64 x i16> %v1, i16 %x0, i32 2 + %v3 = insertelement <64 x i16> %v2, i16 %x1, i32 3 + %v4 = insertelement <64 x i16> %v3, i16 %x0, i32 4 + %v5 = insertelement <64 x i16> %v4, i16 %x1, i32 5 + %v6 = insertelement <64 x i16> %v5, i16 %x0, i32 6 + %v7 = insertelement <64 x i16> %v6, i16 %x1, i32 7 + %v8 = insertelement <64 x i16> %v7, i16 %x0, i32 8 + %v9 = insertelement <64 x i16> %v8, i16 %x1, i32 9 + %v10 = insertelement <64 x i16> %v9, i16 %x0, i32 10 + %v11 = insertelement <64 x i16> %v10, i16 %x1, i32 11 + %v12 = insertelement <64 x i16> %v11, i16 %x0, i32 12 + %v13 = insertelement <64 x i16> %v12, i16 %x1, i32 13 + %v14 = insertelement <64 x i16> %v13, i16 %x0, i32 14 + %v15 = insertelement <64 x i16> %v14, i16 %x1, i32 15 + %v16 = insertelement <64 x i16> %v15, i16 %x0, i32 16 + %v17 = insertelement <64 x i16> %v16, i16 %x1, i32 17 + %v18 = insertelement <64 x i16> %v17, i16 %x0, i32 18 + %v19 = insertelement <64 x i16> %v18, i16 %x1, i32 19 + %v20 = insertelement <64 x i16> %v19, i16 %x0, i32 20 + %v21 = insertelement <64 x i16> %v20, i16 %x1, i32 21 + %v22 = insertelement <64 x i16> %v21, i16 %x0, i32 22 + %v23 = insertelement <64 x i16> %v22, i16 %x1, i32 23 + %v24 = insertelement <64 x i16> %v23, i16 %x0, i32 24 + %v25 = insertelement <64 x i16> %v24, i16 %x1, i32 25 + %v26 = insertelement <64 x i16> %v25, i16 %x0, i32 26 + %v27 = insertelement <64 x i16> %v26, i16 %x1, i32 27 + %v28 = insertelement <64 x i16> %v27, i16 %x0, i32 28 + %v29 = insertelement <64 x i16> %v28, i16 %x1, i32 29 + %v30 = insertelement <64 x i16> %v29, i16 %x0, i32 30 + %v31 = insertelement <64 x i16> %v30, i16 %x1, i32 31 + %v32 = insertelement <64 x i16> %v31, i16 %y, i32 32 + %v33 = insertelement <64 x i16> %v32, i16 %x1, i32 33 + %v34 = insertelement <64 x i16> %v33, i16 %x0, i32 34 + %v35 = insertelement <64 x i16> %v34, i16 %x1, i32 35 + %v36 = insertelement <64 x i16> %v35, i16 %x0, i32 36 + %v37 = insertelement <64 x i16> %v36, i16 %y, i32 37 + %v38 = insertelement <64 x i16> %v37, i16 %x0, i32 38 + %v39 = insertelement <64 x i16> %v38, i16 %x1, i32 39 + %v40 = insertelement <64 x i16> %v39, i16 %x0, i32 40 + %v41 = insertelement <64 x i16> %v40, i16 %x1, i32 41 + %v42 = insertelement <64 x i16> %v41, i16 %y, i32 42 + %v43 = insertelement <64 x i16> %v42, i16 %x1, i32 43 + %v44 = insertelement <64 x i16> %v43, i16 %x0, i32 44 + %v45 = insertelement <64 x i16> %v44, i16 %x1, i32 45 + %v46 = insertelement <64 x i16> %v45, i16 %x0, i32 46 + %v47 = insertelement <64 x i16> %v46, i16 %y, i32 47 + %v48 = insertelement <64 x i16> %v47, i16 %x0, i32 48 + %v49 = insertelement <64 x i16> %v48, i16 %x1, i32 49 + %v50 = insertelement <64 x i16> %v49, i16 %x0, i32 50 + %v51 = insertelement <64 x i16> %v50, i16 %x1, i32 51 + %v52 = insertelement <64 x i16> %v51, i16 %x0, i32 52 + %v53 = insertelement <64 x i16> %v52, i16 %x1, i32 53 + %v54 = insertelement <64 x i16> %v53, i16 %x0, i32 54 + %v55 = insertelement <64 x i16> %v54, i16 %x1, i32 55 + %v56 = insertelement <64 x i16> %v55, i16 %x0, i32 56 + %v57 = insertelement <64 x i16> %v56, i16 %x1, i32 57 + %v58 = insertelement <64 x i16> %v57, i16 %x0, i32 58 + %v59 = insertelement <64 x i16> %v58, i16 %x1, i32 59 + %v60 = insertelement <64 x i16> %v59, i16 %x0, i32 60 + %v61 = insertelement <64 x i16> %v60, i16 %x1, i32 61 + %v62 = insertelement <64 x i16> %v61, i16 %x0, i32 62 + %v63 = insertelement <64 x i16> %v62, i16 %x1, i32 63 + store <64 x i16> %v63, ptr %out, align 128 + ret void +} + +define void @splat_i16_into_i16_vector(ptr %out, i16 %x) #0 { +; CHECK-LABEL: splat_i16_into_i16_vector: +; CHECK: v{{[0-9]+}}.h = vsplat(r{{[0-9]+}}) +; CHECK: vmem +entry: + %v0 = insertelement <64 x i16> poison, i16 %x, i32 0 + %v1 = shufflevector <64 x i16> %v0, <64 x i16> poison, <64 x i32> zeroinitializer + store <64 x i16> %v1, ptr %out, align 128 + ret void +} + +attributes #0 = { nounwind "target-cpu"="hexagonv75" "target-features"="+hvxv75,+hvx-length128b" } From 41a35a7d99604174c442c975ef1472498a47e643 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Fri, 10 Jul 2026 13:08:24 +0200 Subject: [PATCH 121/125] [clang][bytecode] Fix comparing member pointers for redeclared `FieldDecl`s (#208660) Use the first decl to compare. --- clang/lib/AST/ByteCode/MemberPointer.cpp | 14 +++++++++++++- clang/test/Modules/templates.mm | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/ByteCode/MemberPointer.cpp b/clang/lib/AST/ByteCode/MemberPointer.cpp index f0c1fe5930261..bccadc4d4fc8f 100644 --- a/clang/lib/AST/ByteCode/MemberPointer.cpp +++ b/clang/lib/AST/ByteCode/MemberPointer.cpp @@ -89,8 +89,20 @@ APValue MemberPointer::toAPValue(const ASTContext &ASTCtx) const { ComparisonCategoryResult MemberPointer::compare(const MemberPointer &RHS) const { - if (this->getDecl() == RHS.getDecl()) { + assert(!isZero()); + assert(!RHS.isZero()); + const auto getCmpDecl = [](const MemberPointer &P) -> const Decl * { + const Decl *D = P.getDecl()->getMostRecentDecl(); + if (const auto *FD = dyn_cast(D)) + D = FD->getFirstDecl(); + return D; + }; + + const Decl *LHSCmpDecl = getCmpDecl(*this); + const Decl *RHSCmpDecl = getCmpDecl(RHS); + + if (LHSCmpDecl == RHSCmpDecl) { if (this->PathLength != RHS.PathLength) return ComparisonCategoryResult::Unordered; diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm index 610de099d398d..567717491eb87 100644 --- a/clang/test/Modules/templates.mm +++ b/clang/test/Modules/templates.mm @@ -1,6 +1,9 @@ // RUN: rm -rf %t // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class // RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class -fexperimental-new-constant-interpreter | FileCheck %s + // expected-no-diagnostics // REQUIRES: x86-registered-target @import templates_left; From 7fcfcf1c5db1d46b6cc85b80be3a24ee887773f9 Mon Sep 17 00:00:00 2001 From: Jan Patrick Lehr Date: Fri, 10 Jul 2026 13:25:21 +0200 Subject: [PATCH 122/125] [OpenMP] Use secure_getenv when read OMPT library path (#208652) An internal review flagged the use of `getenv` when reading the OMPT tool library path from the environment and passing it to the loader as a potential vuln. This patch replaces the use of getenv in question with the use of secure_getenv on glibc platforms. On non glibc platforms, no change is implemented. --- openmp/runtime/src/ompt-general.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp index a708a8d76fcf4..1682f7e74bd14 100644 --- a/openmp/runtime/src/ompt-general.cpp +++ b/openmp/runtime/src/ompt-general.cpp @@ -60,6 +60,12 @@ static FILE *verbose_file; static int verbose_init; +#if defined(__GLIBC__) +#define OMPT_GETENV secure_getenv +#else +#define OMPT_GETENV getenv +#endif + /***************************************************************************** * types ****************************************************************************/ @@ -281,7 +287,7 @@ ompt_try_start_tool(unsigned int omp_version, const char *runtime_version) { // Try tool-libraries-var ICV OMPT_VERBOSE_INIT_CONTINUED_PRINT("Failed.\n"); - const char *tool_libs = getenv("OMP_TOOL_LIBRARIES"); + const char *tool_libs = OMPT_GETENV("OMP_TOOL_LIBRARIES"); if (tool_libs) { OMPT_VERBOSE_INIT_PRINT("Searching tool libraries...\n"); OMPT_VERBOSE_INIT_PRINT("OMP_TOOL_LIBRARIES = %s\n", tool_libs); From 68e1d0c97d92eb89821d71490bb8d299e9202f03 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 10 Jul 2026 21:26:48 +1000 Subject: [PATCH 123/125] [orc-rt] Add backend-independent category and level APIs to Logging.h (#208696) Add orc_rt_log_Category_getName, orc_rt_log_Level_getName, and orc_rt_log_Level_parse. These are independent of the logging backend and will be used by the printf backend and by upcoming test tools. --- orc-rt/include/orc-rt-c/Logging.h | 34 +++++++++++++++++ orc-rt/include/orc-rt-c/config.h.in | 2 + orc-rt/lib/executor/CMakeLists.txt | 1 + orc-rt/lib/executor/Logging.cpp | 57 +++++++++++++++++++++++++++++ orc-rt/test/unit/LoggingTest.cpp | 54 ++++++++++++++++++++++++++- 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 orc-rt/lib/executor/Logging.cpp diff --git a/orc-rt/include/orc-rt-c/Logging.h b/orc-rt/include/orc-rt-c/Logging.h index e2558a6e01319..39dfe4738b376 100644 --- a/orc-rt/include/orc-rt-c/Logging.h +++ b/orc-rt/include/orc-rt-c/Logging.h @@ -51,8 +51,42 @@ ORC_RT_C_EXTERN_C_BEGIN */ typedef enum { orc_rt_log_Category_General, + + /* + * Count is the number of defined categories; it is not itself a valid + * category. + */ + orc_rt_log_Category_Count } orc_rt_log_Category; +/** + * Logging levels are integers. Valid values are ORC_RT_LOG_LEVEL_DEBUG, + * ORC_RT_LOG_LEVEL_INFO, ORC_RT_LOG_LEVEL_WARNING, ORC_RT_LOG_LEVEL_ERROR, and + * ORC_RT_LOG_LEVEL_NONE. + */ +typedef int orc_rt_log_Level; + +/** + * Returns the display name for the given category, or null if the category is + * unrecognized. + */ +const char * +orc_rt_log_Category_getName(orc_rt_log_Category Cat) ORC_RT_C_NOTHROW; + +/** + * Returns the display name for the given log level, or null if the log level + * is unrecognized. + */ +const char *orc_rt_log_Level_getName(orc_rt_log_Level L) ORC_RT_C_NOTHROW; + +/** + * Returns the level corresponding to the given level name, or -1 if the level + * name is unrecognized. + * + * Comparison is case-insensitive. + */ +orc_rt_log_Level orc_rt_log_Level_parse(const char *Str) ORC_RT_C_NOTHROW; + /** * Declared but never defined: referenced only in unevaluated (sizeof) contexts * to type-check a printf-style format string against its arguments without diff --git a/orc-rt/include/orc-rt-c/config.h.in b/orc-rt/include/orc-rt-c/config.h.in index f5eef7fa4ce55..054a67d89ef28 100644 --- a/orc-rt/include/orc-rt-c/config.h.in +++ b/orc-rt/include/orc-rt-c/config.h.in @@ -21,6 +21,8 @@ #define ORC_RT_LOG_LEVEL_INFO 1 #define ORC_RT_LOG_LEVEL_WARNING 2 #define ORC_RT_LOG_LEVEL_ERROR 3 +#define ORC_RT_LOG_LEVEL_NONE 4 +#define ORC_RT_LOG_LEVEL_COUNT (ORC_RT_LOG_LEVEL_NONE + 1) /* Fail loudly if CMake derived a symbol that isn't defined above. */ #ifndef @ORC_RT_LOG_LEVEL_VALUE@ #error "Invalid ORC_RT_LOG_LEVEL" diff --git a/orc-rt/lib/executor/CMakeLists.txt b/orc-rt/lib/executor/CMakeLists.txt index dddd86f8c0d89..6b621541e3c58 100644 --- a/orc-rt/lib/executor/CMakeLists.txt +++ b/orc-rt/lib/executor/CMakeLists.txt @@ -5,6 +5,7 @@ set(files Error.cpp ExecutorProcessInfo.cpp InProcessControllerAccess.cpp + Logging.cpp NativeDylibManager.cpp RTTI.cpp Service.cpp diff --git a/orc-rt/lib/executor/Logging.cpp b/orc-rt/lib/executor/Logging.cpp new file mode 100644 index 0000000000000..098c21c4ed9f5 --- /dev/null +++ b/orc-rt/lib/executor/Logging.cpp @@ -0,0 +1,57 @@ +//===- Logging.cpp --------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Contains the implementation of APIs in the orc-rt-c/Logging.h header. +// +//===----------------------------------------------------------------------===// + +#include "orc-rt-c/Logging.h" + +#include +#include +#include + +static const char *CategoryNames[orc_rt_log_Category_Count] = {"General"}; + +static const char *LevelNames[ORC_RT_LOG_LEVEL_COUNT] = { + "debug", "info", "warning", "error", "none", +}; + +const char *orc_rt_log_Category_getName(orc_rt_log_Category Cat) noexcept { + if (Cat < 0 || Cat >= orc_rt_log_Category_Count) + return nullptr; + return CategoryNames[Cat]; +} + +const char *orc_rt_log_Level_getName(orc_rt_log_Level L) noexcept { + if (L < 0 || L >= ORC_RT_LOG_LEVEL_COUNT) + return nullptr; + return LevelNames[L]; +} + +orc_rt_log_Level orc_rt_log_Level_parse(const char *Str) noexcept { + + auto StrMatches = [&](const char *LevelName) { + size_t Size = strlen(LevelName) + 1; // include null terminator. + + for (size_t I = 0; I != Size; ++I) { + unsigned char P = LevelName[I]; + unsigned char Q = Str[I]; + assert((!P || std::islower(P)) && "Level name is not all lowercase"); + if (std::tolower(Q) != P) + return false; + } + return true; + }; + + for (int I = 0; I != ORC_RT_LOG_LEVEL_COUNT; ++I) + if (StrMatches(LevelNames[I])) + return I; + + return -1; +} diff --git a/orc-rt/test/unit/LoggingTest.cpp b/orc-rt/test/unit/LoggingTest.cpp index 0c1a4bfa00373..f62dbeca5a219 100644 --- a/orc-rt/test/unit/LoggingTest.cpp +++ b/orc-rt/test/unit/LoggingTest.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// Unit tests for the ORC runtime logging API (orc-rt-c/Logging.h). +// Unit tests for the logging-backend-independent parts of orc-rt-c/Logging.h. // //===----------------------------------------------------------------------===// @@ -26,6 +26,58 @@ TEST(LoggingTest, CompilesAtEveryLevel) { SUCCEED(); } +TEST(LoggingTest, LevelGetName) { + EXPECT_STREQ("debug", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_DEBUG)); + EXPECT_STREQ("info", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_INFO)); + EXPECT_STREQ("warning", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_WARNING)); + EXPECT_STREQ("error", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_ERROR)); + EXPECT_STREQ("none", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_NONE)); + + // Out-of-range levels have no name. + EXPECT_EQ(nullptr, orc_rt_log_Level_getName(-1)); + EXPECT_EQ(nullptr, orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_COUNT)); + EXPECT_EQ(nullptr, orc_rt_log_Level_getName(100)); +} + +TEST(LoggingTest, LevelParse) { + EXPECT_EQ(ORC_RT_LOG_LEVEL_DEBUG, orc_rt_log_Level_parse("debug")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_INFO, orc_rt_log_Level_parse("info")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_WARNING, orc_rt_log_Level_parse("warning")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_ERROR, orc_rt_log_Level_parse("error")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_NONE, orc_rt_log_Level_parse("none")); + + // Parsing is case-insensitive. + EXPECT_EQ(ORC_RT_LOG_LEVEL_INFO, orc_rt_log_Level_parse("INFO")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_WARNING, orc_rt_log_Level_parse("WaRnInG")); + + // Unrecognized names, including prefixes/superstrings of valid ones and the + // empty string, return -1. + EXPECT_EQ(-1, orc_rt_log_Level_parse("")); + EXPECT_EQ(-1, orc_rt_log_Level_parse("inf")); + EXPECT_EQ(-1, orc_rt_log_Level_parse("infox")); + EXPECT_EQ(-1, orc_rt_log_Level_parse("bogus")); +} + +TEST(LoggingTest, LevelParseGetNameRoundTrip) { + // Every level's canonical name parses back to that level. + for (orc_rt_log_Level Level = ORC_RT_LOG_LEVEL_DEBUG; + Level != ORC_RT_LOG_LEVEL_COUNT; ++Level) { + const char *Name = orc_rt_log_Level_getName(Level); + ASSERT_NE(nullptr, Name) << "level " << Level << " has no name"; + EXPECT_EQ(Level, orc_rt_log_Level_parse(Name)) << "round trip for " << Name; + } +} + +TEST(LoggingTest, CategoryGetName) { + EXPECT_STREQ("General", + orc_rt_log_Category_getName(orc_rt_log_Category_General)); + + // The Count sentinel is not a real category, and out-of-range values have no + // name. + EXPECT_EQ(nullptr, orc_rt_log_Category_getName(orc_rt_log_Category_Count)); + EXPECT_EQ(nullptr, orc_rt_log_Category_getName((orc_rt_log_Category)-1)); +} + #if ORC_RT_LOG_BACKEND == ORC_RT_LOG_BACKEND_NONE // Increments Count and returns a printable value, so a test can observe whether From 0ea6d9d0d6fa07da8122514125c09c92d4f66650 Mon Sep 17 00:00:00 2001 From: Aaditya <115080342+easyonaadit@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:05:40 +0530 Subject: [PATCH 124/125] [AMDGPU] Extend wave reduction intrinsics to Pre-gfx8 (#208071) Add support for gfx6/7 families. These subtargets don't support 64-bit Scalar Compares or S_MUL_HI_U32. Added workarounds for these where they come up in the code path. --- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 68 +- .../CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll | 651 +++++++++++++++- .../CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll | 474 ++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll | 494 ++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll | 494 ++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll | 474 ++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll | 724 ++++++++++++++++-- .../CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll | 520 +++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll | 490 ++++++++++++ .../CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll | 576 ++++++++++++++ 10 files changed, 4875 insertions(+), 90 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 4b2fd87c5b078..9cf33b4ccbb87 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -6015,7 +6015,8 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); Register Op1L_Op0H_Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); - Register CarryReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); + Register CarryReg = + MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass); Register AddReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); Register NegatedValLo = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); @@ -6042,9 +6043,23 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), DestSub0) .addReg(Op1L) .addReg(LowOpcode); - BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_HI_U32), CarryReg) - .addReg(Op1L) - .addReg(LowOpcode); + if (ST.hasScalarMulHiInsts()) { + BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_HI_U32), CarryReg) + .addReg(Op1L) + .addReg(LowOpcode); + } else { + Register VCarryReg = + MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + Register LowOpVGPR = + MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + BuildMI(BB, MI, DL, TII->get(AMDGPU::COPY), LowOpVGPR) + .addReg(LowOpcode); + BuildMI(BB, MI, DL, TII->get(AMDGPU::V_MUL_HI_U32_e64), VCarryReg) + .addReg(Op1L) + .addReg(LowOpVGPR); + BuildMI(BB, MI, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), CarryReg) + .addReg(VCarryReg); + } BuildMI(BB, MI, DL, TII->get(AMDGPU::S_MUL_I32), Op1H_Op0L_Reg) .addReg(Op1H) .addReg(LowOpcode); @@ -6365,10 +6380,23 @@ static MachineBasicBlock *lowerWaveReduce(MachineInstr &MI, ActiveBits.addReg(NewActiveBitsReg).addMBB(ComputeLoop); // Creating branching - unsigned CMPOpc = IsWave32 ? AMDGPU::S_CMP_LG_U32 : AMDGPU::S_CMP_LG_U64; - BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc)) - .addReg(NewActiveBitsReg) - .addImm(0); + MachineInstrBuilder SetSCCInstr; + if (!ST.hasScalarCompareEq64()) { + // For targets <= gfx7, use an S_OR_B32/B64 instruction to set SCC. + Register LaneMaskReg = MRI.createVirtualRegister(WaveMaskRegClass); + unsigned CMPOpc = IsWave32 ? AMDGPU::S_OR_B32 : AMDGPU::S_OR_B64; + SetSCCInstr = + BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc), LaneMaskReg); + } else { + unsigned CMPOpc = + IsWave32 ? AMDGPU::S_CMP_LG_U32 : AMDGPU::S_CMP_LG_U64; + SetSCCInstr = BuildMI(*ComputeLoop, I, DL, TII->get(CMPOpc)); + } + SetSCCInstr.addReg(NewActiveBitsReg); + if (ST.hasScalarCompareEq64()) + SetSCCInstr.addImm(0); + else + SetSCCInstr.addReg(NewActiveBitsReg); BuildMI(*ComputeLoop, I, DL, TII->get(AMDGPU::S_CBRANCH_SCC1)) .addMBB(ComputeLoop); @@ -8236,6 +8264,30 @@ void SITargetLowering::ReplaceNodeResults(SDNode *N, case ISD::INTRINSIC_WO_CHAIN: { unsigned IID = N->getConstantOperandVal(0); switch (IID) { + case Intrinsic::amdgcn_wave_reduce_min: + case Intrinsic::amdgcn_wave_reduce_umin: + case Intrinsic::amdgcn_wave_reduce_max: + case Intrinsic::amdgcn_wave_reduce_umax: + case Intrinsic::amdgcn_wave_reduce_add: + case Intrinsic::amdgcn_wave_reduce_sub: + case Intrinsic::amdgcn_wave_reduce_and: + case Intrinsic::amdgcn_wave_reduce_or: + case Intrinsic::amdgcn_wave_reduce_xor: { + EVT VT = N->getValueType(0); + if (isTypeLegal(VT)) + return; + SDLoc SL(N); + bool NeedsSignExt = IID == Intrinsic::amdgcn_wave_reduce_min || + IID == Intrinsic::amdgcn_wave_reduce_max || + IID == Intrinsic::amdgcn_wave_reduce_add || + IID == Intrinsic::amdgcn_wave_reduce_sub; + unsigned ExtOpc = NeedsSignExt ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; + SDValue ExtSrc = DAG.getNode(ExtOpc, SL, MVT::i32, N->getOperand(1)); + SDValue Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, SL, MVT::i32, + N->getOperand(0), ExtSrc, N->getOperand(2)); + Results.push_back(DAG.getNode(ISD::TRUNCATE, SL, VT, Result)); + return; + } case Intrinsic::amdgcn_make_buffer_rsrc: Results.push_back(lowerPointerAsRsrcIntrin(N, DAG)); return; diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll index 8579a2a9f64fc..08645068ac4cf 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.add.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,36 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -250,6 +282,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_add_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_add_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -504,6 +582,34 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -690,6 +796,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -952,6 +1098,34 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1138,6 +1312,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1496,6 +1710,56 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2432,6 +2696,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2790,6 +3094,86 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_add_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3338,16 +3722,60 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[4:5] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s8 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s1, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s3, s8 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s1, s2 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[4:5] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s8 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s1, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s3, s8 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s1, s2 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s4 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v2, s2, v0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s1 ; GFX8DAGISEL-NEXT: s_mul_i32 s0, s2, s4 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s1, s2, s4 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s1, v2 ; GFX8DAGISEL-NEXT: s_mul_i32 s2, s3, s4 ; GFX8DAGISEL-NEXT: s_add_u32 s1, s1, s2 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -3359,15 +3787,17 @@ define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 ; GFX8GISEL: ; %bb.0: ; %entry ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: s_mov_b64 s[4:5], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s5, s[4:5] -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s4, s2, s5 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s5 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s5 -; GFX8GISEL-NEXT: s_add_u32 s5, s2, s3 +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s4 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s4 ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s4, v0 +; GFX8GISEL-NEXT: s_add_u32 s3, s4, s3 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s3 ; GFX8GISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8GISEL-NEXT: flat_store_dwordx2 v[2:3], v[0:1] ; GFX8GISEL-NEXT: s_endpgm @@ -3555,6 +3985,56 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_add_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_addc_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3832,6 +4312,94 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX6DAGISEL-NEXT: s_add_u32 s7, s2, s3 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX6DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX7DAGISEL-NEXT: s_add_u32 s7, s2, s3 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX7DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3844,10 +4412,12 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8DAGISEL-NEXT: ; %bb.1: ; %else ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s7 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 ; GFX8DAGISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s7 ; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 ; GFX8DAGISEL-NEXT: s_add_u32 s7, s2, s3 ; GFX8DAGISEL-NEXT: .LBB11_2: ; %Flow ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) @@ -3855,16 +4425,19 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 ; GFX8DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8DAGISEL-NEXT: ; %bb.3: ; %if ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] -; GFX8DAGISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s4, s5 +; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 -; GFX8DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX8DAGISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8DAGISEL-NEXT: .LBB11_4: ; %endif ; GFX8DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -3882,10 +4455,12 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL-NEXT: ; %bb.1: ; %else ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s7 ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 ; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s7 ; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s7 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s2, v0 ; GFX8GISEL-NEXT: s_add_u32 s7, s2, s3 ; GFX8GISEL-NEXT: .LBB11_2: ; %Flow ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) @@ -3897,14 +4472,16 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL-NEXT: ; %bb.3: ; %if ; GFX8GISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s7, s[6:7] -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8GISEL-NEXT: s_add_u32 s7, s4, s5 +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8GISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s7, v0 +; GFX8GISEL-NEXT: s_add_u32 s5, s7, s5 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 ; GFX8GISEL-NEXT: .LBB11_4: ; %endif ; GFX8GISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 @@ -4382,6 +4959,32 @@ endif: } define amdgpu_kernel void @constant_value(ptr addrspace(1) %out) { +; GFX6DAGISEL-LABEL: constant_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, 0x10000 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: constant_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, 0x10000 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: constant_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll index 947b26df5a569..6b7d8ee27bd98 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.and.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_and_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_and_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2090,6 +2334,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2423,6 +2707,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2888,6 +3244,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -2994,6 +3376,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_and_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3234,6 +3664,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll index 1a9e6f3a34475..132612c1f5e6f 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.max.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s10, 1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_max_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s10, 1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_max_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -400,6 +472,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -512,6 +606,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -755,6 +889,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -867,6 +1023,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1204,6 +1400,64 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2180,6 +2434,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2517,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, 1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_max_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2982,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3088,6 +3480,64 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, 0 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, 1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3386,6 +3836,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll index 2c564bccf1678..c19059b754831 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.min.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s4, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s10, -2 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_min_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s10, -2 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_min_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -400,6 +472,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -512,6 +606,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -755,6 +889,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -867,6 +1023,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1204,6 +1400,64 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2180,6 +2434,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2517,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_brev_b32 s6, -2 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_min_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2982,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3088,6 +3480,64 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX6DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s8, -1 +; GFX7DAGISEL-NEXT: s_brev_b32 s9, -2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_i64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3386,6 +3836,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll index 1ae2a4268ff1e..740b83329ad44 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.or.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_or_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_or_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2090,6 +2334,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2423,6 +2707,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_or_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2888,6 +3244,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -2994,6 +3376,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3235,6 +3665,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll index e5403a9a7d614..1f51a317cdc08 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.sub.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,38 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sext_i32_i16 s6, s6 +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -270,6 +304,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_sub_i32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_bfe_i32 v2, v2, 0, 16 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_sub_i32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -524,6 +604,36 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -725,6 +835,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -987,6 +1137,36 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s5, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1188,6 +1368,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1561,6 +1781,56 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2527,6 +2797,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2900,6 +3210,88 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_sub_i32 s3, 0, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s3, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_sub_i32 s3, 0, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s3, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_sub_i32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3461,19 +3853,71 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_sub_i32 s1, 0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s1 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s0, s1, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s8, s2, s0 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s2, s1 +; GFX6DAGISEL-NEXT: s_add_u32 s1, s1, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_sub_i32 s1, 0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s1 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s0, s1, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s8, s2, s0 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s2, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s2, s1 +; GFX7DAGISEL-NEXT: s_add_u32 s1, s1, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] ; GFX8DAGISEL-NEXT: s_sub_i32 s4, 0, s4 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v2, s4 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v2, s2, v2 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s0 ; GFX8DAGISEL-NEXT: s_ashr_i32 s0, s4, 31 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s1 ; GFX8DAGISEL-NEXT: s_mul_i32 s1, s2, s0 ; GFX8DAGISEL-NEXT: s_mul_i32 s0, s2, s4 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s4 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s2, v2 ; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s4 ; GFX8DAGISEL-NEXT: s_add_u32 s2, s2, s3 ; GFX8DAGISEL-NEXT: s_add_u32 s1, s2, s1 @@ -3487,17 +3931,19 @@ define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: s_mov_b64 s[4:5], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] -; GFX8GISEL-NEXT: s_sub_i32 s5, 0, s4 -; GFX8GISEL-NEXT: s_ashr_i32 s4, s5, 31 -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s4 -; GFX8GISEL-NEXT: s_mul_i32 s4, s2, s5 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s5 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s5 -; GFX8GISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8GISEL-NEXT: s_add_u32 s5, s2, s6 +; GFX8GISEL-NEXT: s_sub_i32 s4, 0, s4 ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s5, s4, 31 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s4 +; GFX8GISEL-NEXT: s_mul_i32 s5, s2, s5 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s6, v0 +; GFX8GISEL-NEXT: s_add_u32 s3, s6, s3 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s4 +; GFX8GISEL-NEXT: s_add_u32 s3, s3, s5 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s3 ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 ; GFX8GISEL-NEXT: v_mov_b32_e32 v2, s0 ; GFX8GISEL-NEXT: flat_store_dwordx2 v[2:3], v[0:1] @@ -3735,6 +4181,56 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX6DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX6DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX6DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s12, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v2, s12 +; GFX7DAGISEL-NEXT: v_readlane_b32 s14, v3, s12 +; GFX7DAGISEL-NEXT: s_sub_u32 s8, s8, s13 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s12 +; GFX7DAGISEL-NEXT: s_subb_u32 s9, s9, s14 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -4012,45 +4508,153 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX6DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s9 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX6DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX6DAGISEL-NEXT: s_add_u32 s9, s3, s2 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s9 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_sub_i32 s7, 0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX6DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX6DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s4, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX6DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s7 +; GFX6DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX6DAGISEL-NEXT: s_add_u32 s7, s5, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX7DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s9 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX7DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX7DAGISEL-NEXT: s_add_u32 s9, s3, s2 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s9 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_4 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_sub_i32 s7, 0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX7DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX7DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s4, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX7DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s7 +; GFX7DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX7DAGISEL-NEXT: s_add_u32 s7, s5, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: .LBB11_4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 -; GFX8DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 -; GFX8DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc -; GFX8DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX8DAGISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX8DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX8DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] ; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_2 ; GFX8DAGISEL-NEXT: ; %bb.1: ; %else -; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8DAGISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8DAGISEL-NEXT: s_ashr_i32 s6, s7, 31 +; GFX8DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX8DAGISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s9 ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8DAGISEL-NEXT: s_mul_i32 s10, s2, s6 -; GFX8DAGISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s2, s2, s7 -; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s2, s10 +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8DAGISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX8DAGISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX8DAGISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX8DAGISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX8DAGISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX8DAGISEL-NEXT: s_add_u32 s9, s3, s2 ; GFX8DAGISEL-NEXT: .LBB11_2: ; %Flow ; GFX8DAGISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s9 ; GFX8DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] ; GFX8DAGISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8DAGISEL-NEXT: ; %bb.3: ; %if ; GFX8DAGISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] ; GFX8DAGISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8DAGISEL-NEXT: s_ashr_i32 s6, s7, 31 -; GFX8DAGISEL-NEXT: s_mul_i32 s8, s4, s6 +; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s7 +; GFX8DAGISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8DAGISEL-NEXT: s_ashr_i32 s8, s7, 31 ; GFX8DAGISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8DAGISEL-NEXT: s_mul_hi_u32 s4, s4, s7 +; GFX8DAGISEL-NEXT: s_mul_i32 s4, s4, s8 +; GFX8DAGISEL-NEXT: v_readfirstlane_b32 s8, v0 ; GFX8DAGISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8DAGISEL-NEXT: s_add_u32 s4, s4, s5 -; GFX8DAGISEL-NEXT: s_add_u32 s7, s4, s8 +; GFX8DAGISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX8DAGISEL-NEXT: s_add_u32 s7, s5, s4 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v0, s6 ; GFX8DAGISEL-NEXT: v_mov_b32_e32 v1, s7 ; GFX8DAGISEL-NEXT: .LBB11_4: ; %endif @@ -4064,44 +4668,48 @@ define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 ; GFX8GISEL: ; %bb.0: ; %entry ; GFX8GISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 ; GFX8GISEL-NEXT: v_cmp_le_u32_e32 vcc, 16, v0 -; GFX8GISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 -; GFX8GISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc -; GFX8GISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX8GISEL-NEXT: ; implicit-def: $sgpr8_sgpr9 +; GFX8GISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX8GISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] ; GFX8GISEL-NEXT: s_cbranch_execz .LBB11_2 ; GFX8GISEL-NEXT: ; %bb.1: ; %else -; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec -; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8GISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8GISEL-NEXT: s_ashr_i32 s6, s7, 31 +; GFX8GISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s8, s[8:9] +; GFX8GISEL-NEXT: s_sub_i32 s9, 0, s8 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s9 ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s10, s2, s6 -; GFX8GISEL-NEXT: s_mul_i32 s6, s2, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s2, s2, s7 -; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s7 -; GFX8GISEL-NEXT: s_add_u32 s2, s2, s3 -; GFX8GISEL-NEXT: s_add_u32 s7, s2, s10 +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s2, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s10, s9, 31 +; GFX8GISEL-NEXT: s_mul_i32 s8, s2, s9 +; GFX8GISEL-NEXT: s_mul_i32 s2, s2, s10 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s10, v0 +; GFX8GISEL-NEXT: s_mul_i32 s3, s3, s9 +; GFX8GISEL-NEXT: s_add_u32 s3, s10, s3 +; GFX8GISEL-NEXT: s_add_u32 s9, s3, s2 ; GFX8GISEL-NEXT: .LBB11_2: ; %Flow ; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] -; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_or_saveexec_b64 s[2:3], s[6:7] +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s8 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s9 ; GFX8GISEL-NEXT: s_xor_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: s_cbranch_execz .LBB11_4 ; GFX8GISEL-NEXT: ; %bb.3: ; %if ; GFX8GISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x34 ; GFX8GISEL-NEXT: s_mov_b64 s[6:7], exec ; GFX8GISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] -; GFX8GISEL-NEXT: s_sub_i32 s7, 0, s6 -; GFX8GISEL-NEXT: s_ashr_i32 s6, s7, 31 -; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) -; GFX8GISEL-NEXT: s_mul_i32 s8, s4, s6 -; GFX8GISEL-NEXT: s_mul_i32 s6, s4, s7 -; GFX8GISEL-NEXT: s_mul_hi_u32 s4, s4, s7 -; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s7 -; GFX8GISEL-NEXT: s_add_u32 s4, s4, s5 -; GFX8GISEL-NEXT: s_add_u32 s7, s4, s8 +; GFX8GISEL-NEXT: s_sub_i32 s6, 0, s6 ; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s6 -; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX8GISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX8GISEL-NEXT: v_mul_hi_u32 v0, s4, v0 +; GFX8GISEL-NEXT: s_ashr_i32 s7, s6, 31 +; GFX8GISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX8GISEL-NEXT: s_mul_i32 s7, s4, s7 +; GFX8GISEL-NEXT: v_readfirstlane_b32 s8, v0 +; GFX8GISEL-NEXT: s_add_u32 s5, s8, s5 +; GFX8GISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX8GISEL-NEXT: s_add_u32 s5, s5, s7 +; GFX8GISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX8GISEL-NEXT: v_mov_b32_e32 v1, s5 ; GFX8GISEL-NEXT: .LBB11_4: ; %endif ; GFX8GISEL-NEXT: s_or_b64 exec, exec, s[2:3] ; GFX8GISEL-NEXT: v_mov_b32_e32 v3, s1 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll index 4d5bd7c29417a..1684aa599344d 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umax.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -182,6 +208,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_max_u32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_max_u32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -450,6 +522,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -562,6 +656,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -805,6 +939,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -917,6 +1073,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1250,6 +1446,62 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2186,6 +2438,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2519,6 +2811,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_max_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2984,6 +3348,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3090,6 +3480,28 @@ entry: } define amdgpu_kernel void @const_value_i64(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: const_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, 0x7b +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, 0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: const_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, 0x7b +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, 0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: const_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -3192,6 +3604,14 @@ entry: } define amdgpu_kernel void @poison_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: poison_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: poison_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: poison_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_endpgm @@ -3244,6 +3664,62 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB12_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB12_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB12_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_gt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB12_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3530,6 +4006,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll index e787784a656ee..29d45ce160a71 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.umin.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,30 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s4, s6, 0xffff +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s2, s[4:5], 0x2c @@ -170,6 +196,52 @@ entry: } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_min_u32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, -1 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_min_u32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -438,6 +510,28 @@ entry: } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -550,6 +644,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -793,6 +927,28 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -905,6 +1061,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1238,6 +1434,62 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2174,6 +2426,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2507,6 +2799,78 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s2, s[4:5], 0xb +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_min_u32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -2972,6 +3336,32 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3078,6 +3468,62 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX6DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX6DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX6DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s16, s[10:11] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v4, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v5, s9 +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s16 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s16 +; GFX7DAGISEL-NEXT: v_cmp_lt_u64_e32 vcc, s[12:13], v[4:5] +; GFX7DAGISEL-NEXT: s_and_b64 s[14:15], vcc, s[10:11] +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s16 +; GFX7DAGISEL-NEXT: s_cselect_b64 s[8:9], s[12:13], s[8:9] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3364,6 +3810,50 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: ; %bb.1: ; %if +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[6:7], exec, s[6:7] +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[6:7], s[6:7] +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s2 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s3 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: ; %bb.1: ; %if +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.2: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[6:7] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll index 84bb41ad62c57..77d89e18dbadd 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.reduce.xor.ll @@ -1,4 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3 +; RUN: llc -mtriple=amdgcn -mcpu=tahiti -global-isel=0 < %s | FileCheck -check-prefixes=GFX6DAGISEL %s +; RUN: llc -mtriple=amdgcn -mcpu=kaveri -global-isel=0 < %s | FileCheck -check-prefixes=GFX7DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=0 < %s | FileCheck -check-prefixes=GFX8DAGISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=tonga -global-isel=1 < %s | FileCheck -check-prefixes=GFX8GISEL %s ; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -global-isel=0 < %s | FileCheck -check-prefixes=GFX9DAGISEL %s @@ -17,6 +19,38 @@ ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=+real-true16 -global-isel=1 < %s | FileCheck -check-prefixes=GFX1132GISEL,GFX1132GISEL-TRUE16 %s define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: uniform_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, 0xffff +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, 0xffff +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_short v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -256,6 +290,52 @@ define amdgpu_kernel void @uniform_value_i16(ptr addrspace(1) %out, i16 %in) { } define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { +; GFX6DAGISEL-LABEL: divergent_value_i16: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX6DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX6DAGISEL-NEXT: s_xor_b32 s10, s10, s12 +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX6DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i16: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: v_and_b32_e32 v2, 0xffff, v2 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s10, s6 +; GFX7DAGISEL-NEXT: .LBB1_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s11, s[8:9] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s11 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[8:9], s11 +; GFX7DAGISEL-NEXT: s_xor_b32 s10, s10, s12 +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[8:9], s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB1_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s10 +; GFX7DAGISEL-NEXT: buffer_store_short v2, v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i16: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -524,6 +604,36 @@ define void @divergent_value_i16(ptr addrspace(1) %out, i16 %in) { } define amdgpu_kernel void @uniform_value(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -712,6 +822,46 @@ entry: } define amdgpu_kernel void @divergent_value(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB3_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB3_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -955,6 +1105,36 @@ entry: } define amdgpu_kernel void @uniform_value_dpp(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s6, s4 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dword s6, s[4:5], 0x2c @@ -1143,6 +1323,46 @@ entry: } define amdgpu_kernel void @divergent_value_dpp(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_value_dpp: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB5_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB5_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_value_dpp: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -1476,6 +1696,54 @@ entry: } define void @divergent_value_dpp_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_dpp_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB6_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB6_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_dpp_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -2328,6 +2596,46 @@ entry: } define amdgpu_kernel void @default_stratergy(ptr addrspace(1) %out) #0 { +; GFX6DAGISEL-LABEL: default_stratergy: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: default_stratergy: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB7_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[4:5] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[4:5], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[4:5], s[4:5] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB7_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: default_stratergy: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 @@ -2661,6 +2969,88 @@ entry: } define amdgpu_kernel void @divergent_cfg(ptr addrspace(1) %out, i32 %in) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX6DAGISEL-NEXT: s_and_b32 s2, s2, 1 +; GFX6DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX6DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX6DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX6DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX6DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX6DAGISEL-NEXT: ; %bb.5: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX6DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr2 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[0:1], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[0:1], exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_load_dword s6, s[4:5], 0xb +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s2, s[2:3] +; GFX7DAGISEL-NEXT: s_and_b32 s2, s2, 1 +; GFX7DAGISEL-NEXT: ; implicit-def: $vgpr0 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s2, s6, s2 +; GFX7DAGISEL-NEXT: .LBB8_2: ; %Flow +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[0:1], s[0:1] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s2 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB8_6 +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[2:3], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: .LBB8_4: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s7, s[2:3] +; GFX7DAGISEL-NEXT: v_readlane_b32 s8, v0, s7 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[2:3], s7 +; GFX7DAGISEL-NEXT: s_xor_b32 s6, s6, s8 +; GFX7DAGISEL-NEXT: s_or_b64 s[8:9], s[2:3], s[2:3] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB8_4 +; GFX7DAGISEL-NEXT: ; %bb.5: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s6 +; GFX7DAGISEL-NEXT: .LBB8_6: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[0:1] +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v1, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 @@ -3178,6 +3568,42 @@ endif: } define amdgpu_kernel void @uniform_value_i64(ptr addrspace(1) %out, i64 %in) #0 { +; GFX6DAGISEL-LABEL: uniform_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX6DAGISEL-NEXT: s_and_b32 s1, s0, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX6DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: uniform_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], exec +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s6, -1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s0 +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s0, s[8:9] +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s1 +; GFX7DAGISEL-NEXT: s_and_b32 s1, s0, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s0, s2, s1 +; GFX7DAGISEL-NEXT: s_mul_i32 s1, s3, s1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s0 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[4:7], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: uniform_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -3369,6 +3795,54 @@ entry: } define void @divergent_value_i64(ptr addrspace(1) %out, i64 %id.x) #0 { +; GFX6DAGISEL-LABEL: divergent_value_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX6DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX6DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX6DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX6DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX6DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX6DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX6DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX6DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX6DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX6DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX6DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX6DAGISEL-NEXT: ; %bb.2: +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX6DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) +; GFX6DAGISEL-NEXT: s_setpc_b64 s[30:31] +; +; GFX7DAGISEL-LABEL: divergent_value_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mov_b32 s6, 0 +; GFX7DAGISEL-NEXT: s_mov_b32 s7, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s4, s6 +; GFX7DAGISEL-NEXT: s_mov_b32 s5, s6 +; GFX7DAGISEL-NEXT: s_mov_b64 s[8:9], 0 +; GFX7DAGISEL-NEXT: s_mov_b64 s[10:11], exec +; GFX7DAGISEL-NEXT: .LBB10_1: ; =>This Inner Loop Header: Depth=1 +; GFX7DAGISEL-NEXT: s_ff1_i32_b64 s14, s[10:11] +; GFX7DAGISEL-NEXT: v_readlane_b32 s12, v2, s14 +; GFX7DAGISEL-NEXT: v_readlane_b32 s13, v3, s14 +; GFX7DAGISEL-NEXT: s_bitset0_b64 s[10:11], s14 +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], s[8:9], s[12:13] +; GFX7DAGISEL-NEXT: s_or_b64 s[12:13], s[10:11], s[10:11] +; GFX7DAGISEL-NEXT: s_cbranch_scc1 .LBB10_1 +; GFX7DAGISEL-NEXT: ; %bb.2: +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v2, s8 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v3, s9 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[2:3], v[0:1], s[4:7], 0 addr64 +; GFX7DAGISEL-NEXT: s_waitcnt vmcnt(0) +; GFX7DAGISEL-NEXT: s_setpc_b64 s[30:31] +; ; GFX8DAGISEL-LABEL: divergent_value_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) @@ -3609,6 +4083,80 @@ entry: } define amdgpu_kernel void @divergent_cfg_i64(ptr addrspace(1) %out, i64 %in, i64 %in2) #0 { +; GFX6DAGISEL-LABEL: divergent_cfg_i64: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX6DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX6DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX6DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX6DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX6DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX6DAGISEL-NEXT: ; %bb.1: ; %else +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_and_b32 s7, s6, 1 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX6DAGISEL-NEXT: s_mul_i32 s7, s3, s7 +; GFX6DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX6DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: ; %bb.3: ; %if +; GFX6DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX6DAGISEL-NEXT: s_and_b32 s6, s6, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX6DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX6DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX6DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: divergent_cfg_i64: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0xd +; GFX7DAGISEL-NEXT: v_cmp_lt_u32_e32 vcc, 15, v0 +; GFX7DAGISEL-NEXT: ; implicit-def: $sgpr6_sgpr7 +; GFX7DAGISEL-NEXT: s_and_saveexec_b64 s[8:9], vcc +; GFX7DAGISEL-NEXT: s_xor_b64 s[8:9], exec, s[8:9] +; GFX7DAGISEL-NEXT: s_cbranch_execz .LBB11_2 +; GFX7DAGISEL-NEXT: ; %bb.1: ; %else +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_and_b32 s7, s6, 1 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_mul_i32 s6, s2, s7 +; GFX7DAGISEL-NEXT: s_mul_i32 s7, s3, s7 +; GFX7DAGISEL-NEXT: .LBB11_2: ; %Flow +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: s_or_saveexec_b64 s[2:3], s[8:9] +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s7 +; GFX7DAGISEL-NEXT: s_xor_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: ; %bb.3: ; %if +; GFX7DAGISEL-NEXT: s_mov_b64 s[6:7], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s6, s[6:7] +; GFX7DAGISEL-NEXT: s_and_b32 s6, s6, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, s6 +; GFX7DAGISEL-NEXT: s_mul_i32 s5, s5, s6 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v1, s5 +; GFX7DAGISEL-NEXT: ; %bb.4: ; %endif +; GFX7DAGISEL-NEXT: s_or_b64 exec, exec, s[2:3] +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: buffer_store_dwordx2 v[0:1], off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: divergent_cfg_i64: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx4 s[0:3], s[4:5], 0x24 @@ -4094,6 +4642,34 @@ endif: } define amdgpu_kernel void @constant_value(ptr addrspace(1) %out) { +; GFX6DAGISEL-LABEL: constant_value: +; GFX6DAGISEL: ; %bb.0: ; %entry +; GFX6DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX6DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX6DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX6DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX6DAGISEL-NEXT: s_mul_i32 s4, s4, 30 +; GFX6DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX6DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX6DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX6DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX6DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX6DAGISEL-NEXT: s_endpgm +; +; GFX7DAGISEL-LABEL: constant_value: +; GFX7DAGISEL: ; %bb.0: ; %entry +; GFX7DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x9 +; GFX7DAGISEL-NEXT: s_mov_b64 s[4:5], exec +; GFX7DAGISEL-NEXT: s_bcnt1_i32_b64 s4, s[4:5] +; GFX7DAGISEL-NEXT: s_and_b32 s4, s4, 1 +; GFX7DAGISEL-NEXT: s_mul_i32 s4, s4, 30 +; GFX7DAGISEL-NEXT: s_mov_b32 s3, 0xf000 +; GFX7DAGISEL-NEXT: s_mov_b32 s2, -1 +; GFX7DAGISEL-NEXT: v_mov_b32_e32 v0, s4 +; GFX7DAGISEL-NEXT: s_waitcnt lgkmcnt(0) +; GFX7DAGISEL-NEXT: buffer_store_dword v0, off, s[0:3], 0 +; GFX7DAGISEL-NEXT: s_endpgm +; ; GFX8DAGISEL-LABEL: constant_value: ; GFX8DAGISEL: ; %bb.0: ; %entry ; GFX8DAGISEL-NEXT: s_load_dwordx2 s[0:1], s[4:5], 0x24 From fcf7f6e97ab3d3e3c400b81df5fdf31c6adc294e Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Fri, 10 Jul 2026 21:56:56 +1000 Subject: [PATCH 125/125] [orc-rt] Rename the "disable logging" level from "none" to "off" (#208697) Rename ORC_RT_LOG_LEVEL_NONE to ORC_RT_LOG_LEVEL_OFF. The old name collided with the "none" backend (a different mechanism) and could be misread as "no filtering" rather than "no output"; "off" avoids both issues. --- orc-rt/include/orc-rt-c/Logging.h | 2 +- orc-rt/include/orc-rt-c/config.h.in | 4 ++-- orc-rt/lib/executor/Logging.cpp | 2 +- orc-rt/test/unit/LoggingTest.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/orc-rt/include/orc-rt-c/Logging.h b/orc-rt/include/orc-rt-c/Logging.h index 39dfe4738b376..26da505bbb491 100644 --- a/orc-rt/include/orc-rt-c/Logging.h +++ b/orc-rt/include/orc-rt-c/Logging.h @@ -62,7 +62,7 @@ typedef enum { /** * Logging levels are integers. Valid values are ORC_RT_LOG_LEVEL_DEBUG, * ORC_RT_LOG_LEVEL_INFO, ORC_RT_LOG_LEVEL_WARNING, ORC_RT_LOG_LEVEL_ERROR, and - * ORC_RT_LOG_LEVEL_NONE. + * ORC_RT_LOG_LEVEL_OFF. */ typedef int orc_rt_log_Level; diff --git a/orc-rt/include/orc-rt-c/config.h.in b/orc-rt/include/orc-rt-c/config.h.in index 054a67d89ef28..c4ff9a0fb4cd2 100644 --- a/orc-rt/include/orc-rt-c/config.h.in +++ b/orc-rt/include/orc-rt-c/config.h.in @@ -21,8 +21,8 @@ #define ORC_RT_LOG_LEVEL_INFO 1 #define ORC_RT_LOG_LEVEL_WARNING 2 #define ORC_RT_LOG_LEVEL_ERROR 3 -#define ORC_RT_LOG_LEVEL_NONE 4 -#define ORC_RT_LOG_LEVEL_COUNT (ORC_RT_LOG_LEVEL_NONE + 1) +#define ORC_RT_LOG_LEVEL_OFF 4 +#define ORC_RT_LOG_LEVEL_COUNT (ORC_RT_LOG_LEVEL_OFF + 1) /* Fail loudly if CMake derived a symbol that isn't defined above. */ #ifndef @ORC_RT_LOG_LEVEL_VALUE@ #error "Invalid ORC_RT_LOG_LEVEL" diff --git a/orc-rt/lib/executor/Logging.cpp b/orc-rt/lib/executor/Logging.cpp index 098c21c4ed9f5..4e321e2762e37 100644 --- a/orc-rt/lib/executor/Logging.cpp +++ b/orc-rt/lib/executor/Logging.cpp @@ -19,7 +19,7 @@ static const char *CategoryNames[orc_rt_log_Category_Count] = {"General"}; static const char *LevelNames[ORC_RT_LOG_LEVEL_COUNT] = { - "debug", "info", "warning", "error", "none", + "debug", "info", "warning", "error", "off", }; const char *orc_rt_log_Category_getName(orc_rt_log_Category Cat) noexcept { diff --git a/orc-rt/test/unit/LoggingTest.cpp b/orc-rt/test/unit/LoggingTest.cpp index f62dbeca5a219..141ce469acc35 100644 --- a/orc-rt/test/unit/LoggingTest.cpp +++ b/orc-rt/test/unit/LoggingTest.cpp @@ -31,7 +31,7 @@ TEST(LoggingTest, LevelGetName) { EXPECT_STREQ("info", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_INFO)); EXPECT_STREQ("warning", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_WARNING)); EXPECT_STREQ("error", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_ERROR)); - EXPECT_STREQ("none", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_NONE)); + EXPECT_STREQ("off", orc_rt_log_Level_getName(ORC_RT_LOG_LEVEL_OFF)); // Out-of-range levels have no name. EXPECT_EQ(nullptr, orc_rt_log_Level_getName(-1)); @@ -44,7 +44,7 @@ TEST(LoggingTest, LevelParse) { EXPECT_EQ(ORC_RT_LOG_LEVEL_INFO, orc_rt_log_Level_parse("info")); EXPECT_EQ(ORC_RT_LOG_LEVEL_WARNING, orc_rt_log_Level_parse("warning")); EXPECT_EQ(ORC_RT_LOG_LEVEL_ERROR, orc_rt_log_Level_parse("error")); - EXPECT_EQ(ORC_RT_LOG_LEVEL_NONE, orc_rt_log_Level_parse("none")); + EXPECT_EQ(ORC_RT_LOG_LEVEL_OFF, orc_rt_log_Level_parse("off")); // Parsing is case-insensitive. EXPECT_EQ(ORC_RT_LOG_LEVEL_INFO, orc_rt_log_Level_parse("INFO"));

roH z{pHo9u6x(qi~mhO%7NtacqDhy`bfAwwl+4gA+5)8=X9vt`(GH|-T=RgY36s)>iRe3 z_M3lJOzE&qEcN)OPMy%0Yk|934Lj{>e^$%Jy{NIuKtt|Eq`V-{sY?4vYX8xpP;hlY zNj5#QXYiFSl(LB8yxhqIu#AtxJyxi+$mV|Z2^Ty|?^BWNoOk{OHt4v)bk2MtJV}?& zD_f(}WfCF)f;iHIvCxtCR|3F>scBhl$aa_4IiI+DtHQWy;uZQnx60L*PjS)(cG(mT zxE^M-Yv(pwyJE2|Lsens#J70BOD($gww(4btkfK*iyLvvX)KrWvIq=G{(e<3FNf^i zK{NAgeusBWf9&s1Iv0IPSN7kdzy38zUlVf{x#~zt5dh|7AOQsYi z(Q((FJzxIolTZKXC%4`1@7ATzQDl00921d%Rj`VZhpNK~W6!Y9 zC%$93h4AA<)Ue>c%?$Tnl#8#v<}01B`Iaar-+!H>=0Ds{<4v;%ghq6CeMo2hX<62$ zT_y$JYFBV3`Droy`SZ_YHLX;=@!7CO~5yd>Vs50_ApEq z;ZbBcMsP{+qO9bA1Hf9P)1)m4kRbYXnGp@shm_Zl#whxV2s@sjN}W3uy6p@?so#6w z1Oi>mve#dG-QIeev9DQuuowABN66CvaBmF6BUNYV1e<_Z$|ZN9O&SAvw|?n5j5Qkf zG*yvzBcT*s{r4v!rYQKuc)jw!-gzd$@-nK5PN6oFlW;(*O&< zEPvGL_xW3PYATmkCDy~mgrg1j?CRfMg$ zyap+57%Ozu6>1;c8zc8C=;H5Y5zC9b(f41{u|W{8fsTvyk9) zG^X_}}f+^=-aM4rU3cKul=9$NHfAgE)^kqAq^L=i-@y6ulfDHeU zo|&FgR#J8|=T)zIE}CZ!@liH+ZsFj;gAK{B16AI@VIWe8J0q%X&#f>4Q@v=^U$$$oVG zHLg5Ax$6(sd-&DnjJ50CVcwe59h!Xhb7?cVLf7{ zG-AaFtusbK=XK;s&Sa$jF5xH_G|wF*PSia$N*5%^(3Qa=GRtxy{#WQMxSy9XLatG*WN!3RLE+8*8ucUb^@1%_US5G=*ld>ijlt_<{lzZw7eTIxe zQjK$RKtg_gvh&5-#IhOphUd(lqkc03uq(f1s?L2XnP^^O-ZOSJw_sQX(a4D9d|-VyZ3Gu2Eo{1gJ`qq?LiiNllvvj`H#f z`{4Z#?BYuENva+)W)z#Ksn~;#; ztF5iQg>%ZUn#hq6d!^wcMvTye4?GLqLB9tj{uJ}(60L*2IQs=_ci_H>Wq4;KsSDx` z5lae2LbK+69$Yvd1wylD^aPtEs=Db=O0L~n6%Kf3$C~-SUjFib1$&+OgGg*{fzMiX zw6Qn+)+RpkbDK2z6Q_D1RSiu%nW^0?Weccq^VQwoJ+5@F=t+C+4)GNFtx8? zQm23%DH#%+W0kjLu_=fKy3+dqvscGRy)YI^M*kU?zD$t0nOY*ouzRj9Au~2_!08Rc zVpGNdc0aeF=bva_yegHDW1!d7(6|19RXcT&x8Hp8^{%+uYD!E<*8I}iWGC9%ZRJcv zVyvKRKlh#^4X5Q-mP15h9^TudOPKliEF^ox!%j+|`sw;v^a-McTPuf?SL*#(0DeinS^s{B! zhZZT`VfQ~j*+t}uX{fam`?tgu4oYF%S6y4#c-9%`2R@nnvB22FY*BhVL<;jyWg`ke zE*#Lm|KC6O=z~yhPK#hUIxVZ#uealRcZbH*a`Y#+OyKn)QEs$#qf{q%Sd1Y~)q{%! zSE#h<(`VR^Zo0`fuU(5i=uM5MopxH_mYZ*Wcg3nzXN(#(Dt>C^)UeHW`4mxzfDTGm zUww5V67=r49b3bN3N}Z!>?1R0&P)KHube!2a=S5O#vsTHvwHvKKCV9E^$#J}1?zU( z@~zbjezC4xTDVhVro;xqE9X!1-+ldeEx&!2KHD~~UcvPmO^ zByZutKfKqU)&FEmiV54R_x;#T?v`S2zVrUR)t~L#x7+j2KX13+e!DBmJ&(R%g*}f) zAtZ_Dgzz3h)8c2vwX+``-)A1a-9CN$?}kC6WoKva1H5`zjiBl5=Sz2>3k?tm;&Fo| z+_j5l**({uWy5d$y~X!E%@QIF4fQKOkDd6yj~DXDC^ofWl;$`*mcC&PINBUHZrqR$ zKm72EdGqEOzyoI)O+FbCgEZNDPd{X@Jo%9IBjj)+l1D`a{K~}e8)o8P z{g}oK(U$t9)2o-@LE{MHiOxIE4|G}eS}7q3EH*Nc)ztukB6RJnp>&V!Shw8Da3vW{ z<1V<;x?*_Tu45NV&u(GCI9!bJ-X=+0#kcsUjxJ#hZjGrQCcsSQa&UjvDg)y;RJjzT zP`>1&iOTi>IVZ#mr9};=ahJ=>Ds0J$<@WiMsrLAz58D>paVqs0J)ZHi6?$IDfM2OR z0Cgo{UoR5K*50NMc3TTTC6&ZM(QUhp3a z_?0i&8mlNSvTf^E+LF05?EROYba~KEQv0q}P}s-fGV&~fD>F1j98gd=Qx6E~`-Q45)>9y(kr!zjI{S=P#iQTozthI%=J56yLNqN z#*7(ZqLg7b)!f_3qi%A82l?_dDu&_O3sx7|vK_VPqbFfxMMO2OHL@2#zHhZVH`4gab@k|Id;#F&a|O7K496sN3)6)vc&kLUn1X$7Be@n4^KqUR5(91A)Eg2y^?~0bHHFdzUevQSGU{cALK4prz)}*caU-W_jWI?&T9@QHF|3tL zj=gc6a`1;%H649w50CZ{y)#s{*NV4qvYm^+;BGICJ^NDp6rW&i0KZu+TC+}%c!P0O zs(>D}V|=7SG=UEx{UC^-vprCR!CZoS zuzNL;LC~|2+=em;TzX(DYN+O@@PDav`l48eW|`hsy)#iF)m|gFjJ>30paD36|8BLXAe+@HIKRo_rn0f>Oc%i0Ydsl2oqaH{PV5r*V@X3Gmrv2ybpDx z7ZfrR?n<;A^pBG8kBb382qq&?6JgL3ccFS6xKaK@=U&(J06vvKo}*w_*VRR}9r{Ui zrHMh!UT;R;wf8_)!kHA*)L4t`1Pu462N~S~dzUO;p<>T!2D>Vpn(A;&Do6N=E3UZe z;RhdC(y@K#_#1AxK`|(TAumTEJ6n*xF`t0blJrz6lF4&$0QEAdaI)s+c0|_M|y_c>3_s!h} z1oTG*r0gVj@7=q%o|!rG&8eB0?l&e(&?9avuc^wdx83RIMNT(yM z2agtWd^1`7@e`7}Vuo}cat&TVWXa;iGJX0qx#NyI)%OW+y@T|w7r_mnf9Nn7vMVGv7A;x><^~R3EC#1y=DzRPn$ly_3#lR+{oIe zZXX|E6~EkaI2-9CHYr6K#aU(R#tqUA>3unl7M)=_2p%<7m<@~Jcz(vErx-|&33Y5-tPDkVx4wP*$X$2e1t+&D^1=(xOa6|{>KQup z9w^q>WU&W?NCSli;HyeohW8-b)838me4vmWYjioV?^teW(}@F&me=Ofa6#$~;0}|i z#t>kOYSy-`qptd^t?O4^G7e!`u<$W?*hybbA;8-k{X*wR67w@r89jzpghn7Mrp+7( zKxb3ZPQtAdR|s{m%Fr(Q5sg^@(5#)OZQ~9o0E-U6vlbxG2wNDs8Zqug7gaadc1H!y8 zczpxLea7Vn7t!vIYbqGa9(YJOe9s{VoDyHjC?O4pgTqe5Bu$Kk6A%V{+A`A_BpS{Q zWV8l2=GYLQ^p{yP`Bq-rlapN{_(wJ1q#f4BAAh_RVeN*)X>1C>sEME#>1|Ca+z-I4 zw@`|^U($!2u&}>h!tFK%yyzm0SY2mr&p8FyP-|5q*54`7|d-}lE%XHC27YQV? zE@XDAgTq4rGW|_$-@bk4HEY(C;~X#O_1?z2CiCPB!&^8eIy!Xd&?z%Bb8z22eYsx~ zKjXRB?>IE*0pg5k!!_t9OScxv_EHCIQ{iO?$u6Zs<^YS^RZ(J}KjUlj+v6XX(Aebb z$_sXWtggjT=F};LwUFjk=mT|8-7k}V@yW9B$M&Ni0pW6oeF%r48U;;4z%XaAF=DqM1+eI}0Vi-a@{@)0w3WnQpwh!EdyA zg2hqm4h9FQGn#b`IIyar&TLF+*U&`qS^)t4G)*|N8BqPyz->zp-HsEtbqbkuLjO^P`w`A z9Z%My&>-#!ngp{3b>r`zD;+ui{+@h6w?x-EOna5@?HT+3{j~S=AE&yN~zo z-P<^C-aL~1q%Z#n3I8lrl#`ld*&wGG(X#giUz$_fxb^~0THOtFRRfDfN?J%R*fdU5 z@hTZ;??O&O+aMdpU`m@An#qa9=%^Dvbh5nlYhYhQ^FX+P-*J}=88TQh+P9N1*vP4Z zOE{G$C!i%-6&n_M89sDU4MtXk>}L6e@G>o}l~M%U*3n!6gA}uz=^%~cBT$k{2@M0n z>#?u4ssbUz_Q;m?%Vqi0FC{B`gSwS5uCb)G>?8q^QDS2(L(FcCKn(O|t;h9Duw~*b zh*_9i1l)Kp1$fojr{M>QM+rEbAl82Qx?FwR!_t4$Z3w+(lk^Cq^k^NgB#1TClK=of z07*naRONbu(VdgCLzkA8>h9F3Q(M^2k)Q-(r~1In>UQ+$(dW{+3+H}=Sf6s|op;(( zQ&ZUrz5GG7$Z7vm1{+9jEu`xES1NAjUQnqH6{QA+e7`Vgb>n|qBdFP(1Xu!#f1_`{t0K5X= zcFEQf*$BxM=mYJK6O(3(Y+Jh!<_VWUBK3n@ICLoZ(gBkOLJFRjS6nSK*O$W4)u7Tt zuUolDp1bWbw=O(U*S^R364$D$(-fWNb_7O24(!t7^7e`?tIUg@89fyba)F1+th`f! z=AOqrX;zAEn21o)n}z<+4E^DNS;N*+S&7VRAwgEzlbtE|T{l3Q_Z%dCP1~r*8fspL zE0`e;b*LH4N%LNR^Fg$xq{Xo(XP`(53-~)Ha@2m3L+CNix{;Z*t{my^w{4K}Et*4i zc$8Jn9eRVb%Q#1(AP9n;JX$WmDlYfw>pMBQz-XYRq@IW!*zE0TJGr9xQ z8S`u{6Q=e)8prdTaspPQDzT1DB7*x^uuSvDiEIYREgZc+Bw;a zF$-W957|1kQ}>CclxCP^7~LTd**F3E8i)%$jp{_c2%56$OdMogG#da)wNNaJ{eH-T zX4|)0GJpAg|0BT*T?P&qD9I@)N}|FasEVOfqELixvAY6yhAP3)R_(GuY%$-@=%P%)UpbL6&CltR(=} zJ8R(i4D}euR^}e#hJMgVE5ZgFTJ$mYp=cbK9-J8J@u5d zZrxhNqAW$$rozHP2XoF(ojR3`g6}TxzWc6ReDTFnjx1%c8BOIrWS;X!G7gGImUFrH z-g_g*k00M>>eOld@x2q4guuYSRsg%}AxItqsWL$)8y%bdk&0J}J|Ho%(M7l)X%6dj z)(K97215@iOf{S{Gjob%Qz3FX!6Vv=fyjh@0h1!fo^9(5D`rnI{qLhU$VZ+5SojaX z0`KR&Ha1VGqBG<1o5Y05PMAp5!1mm3jgh#ngJFsMtlV(zRWe|}0QEvt({ixYNURN- z?A!zdA()wKmy(?)@^Fd3AndV%f#zYqr{*tn)DY}a&c%DUB8SL<=H>J zZ_fPT{eZ^pdrG4YeI=|>y4xL-sEciJc3q#b?+%*#;*D?NSWbjk=chye!E2n*LRx#x z8fGGub+eHpN4n6bP{{yaG{M?ahA0~dr--nMy%3XkK4S8APD92>^a}&|K8iO!fckP8 zd}x9hG6rx4v{|-g^#?&1&9JCBt;ZgN&J6oqgqXC3NpgIu=sWe6hSDN{-%W7xdsQtA z`PqBuRdDXiKwRS#u^`SbvSR??BH;G4|({xMf#ixr7FmAzpicBq44i zW0#v5=97KKiBDxit+6AyM(tq~FjFR>HD1QfR~(_1G0aUHW}ZCwCHSv8qeW$Iv`v?Lq>C=?F&OVYy9(1zyDu8 zfsK#x4XHX|{8B3%L5!89Qd_uNmd&58t_u~f+;rm@>Cv;N#Ka)V0SX5RJU`nE9+}cq zbWLTFfvEQYpGD;`S=firWC)O7kCv_j_%guUfwp%_nv0H04^^|DzXsImYou@wlR>PO zRdarlRg31R`#^*%&H7y|L5Qy4_7744vDL7|j>8x&D8%RNKyEnLd4@tYi(|JW%ODWv z)@fZ(4|+$vY@GK!!pyXX?ORg}7Iq2ohdBeX^pFHPOc20uTr+=}!S<->qO{Jf>2gnf z0y(Ibf{K*jGb1G>W%whHJTe^HO|VeMorp#8iou8+GH%>BJ4_P{0IUQpMtbuj3cv`& z)O{LYHyis*$jYN*q6mOp8mj-#vtT7r)z#I(20yAi{(7*Z<^Y%zbQJSuPH7qt)a_>*Zyny4Y4BLz)u=JQBlfy~ z{=NRn6L@gE=Tx-I{aYBvFgb)}IsTNG3g8z^3zA;O#dTwxG$J`iVqCH$b?qgN(h}L0 zwOT%Wd7QdJ^A@e7TmMTW9VQVmjZ(!wC=Azue+wp(I%r!BoG~&jDz06MVE2W&wUWKN zN}`aryK!_7?0u~gYSF|=+& zQPMG^qXZ(TI}06b)YyW?%0Yzhp!G^U?1JiLXHl)>7S$kbt|qxPVjwqJC{uyt76ZH9 zi9rSfjUKbg20Ns`d0S;CK<>IFvt{ATpVU40k=|>t1Y+i;hvS(YZq!tbz`#p6tnro@ zq13{`O}(wQ6W{oTJeWmWa}@LLQM*rr54IVqW*Gj)kBkR1cUN^8r_gd1QVIJ9hhng= zli1h*Bu_w`Va)3F@EF{+XOHRiH{OuOjT=v6b}$r@@3bkj!6NA8ddH3(U*pBT2GG=B zef8D;@bphcOxC_Hz4X#0KmGJm@9y2ZBffnwrMjGHs&dm!HyHtVKgJh`$i)t@OWwlY z$pBR=^L#JDy2#nkupMg_{&vJ>hQ7~pfzfo&Uw7?w>F4$B3wTA#Um3BWGCDv$++Ja7NAbLS~m zA{wQ&Kn!h@I|g=}77zlE7Zce!^%~*fksiC;gULz|z=qF%Z9fFypg#9evx5Q#rJNPH ziN0}YVPX-Agki~`{1XVT!6^}{lm=X~?x{x~pp=K@TP`=gv(ohWv)6XdSv_+&mLV`n zYZRB!hrhpVGFg||?KK3xtmBh*faJrTghf@((4j+@0PyZvy?S*5051bE7%b3wHiBxs zr~;{mQ7b8kw!>1IzemCl!{2)l8 z$&bUqc{6|su1oWFjxS8^lwVdUA&8oh7z2CX=s;w8gZUr_e%xG-HOF?rxiq#22?>!t zy?d*qQaAokIwj<)gLUr0zS6wY*#*C59ojXDm4Cx>W0TYV?$ZU{ATtLdq zd{$UdCp(b?opy)S^p*yo^)sT!;NCV2KJ>OlzI5zEcg1-%kRb2gvO(4?og-5wQ9z=V zgmzses&N`Jo<)ic_CGbMljBiwZxzFkgPNz4^9&8ndrnp>ZAOgOI;dz&;h-I-#U^W* z?T2bE{u#hMs*x_4B^6nFAiBbqOX9<=s{R?V0D#w(mzzuSY=ugHCG3@WxW;j~b()le z91qABpc#Z(0g}7VKKqP@Zd_i+(&oVjAG`s}RWH8yVi?0-B_$ zy_aAipgfWUPpbknPy9|A9ue$#ZNhN9A-L{cx7~KD%jD;0bWl41I}@JFqzTKj3#1Uz ztRVC^ox5JvES_us?>*P@zHmfo{&-%_rY8Y*`Bl9W)~Bjem+#;$iIK4gtpwf>CV~fe* zG}{bTdwBCU!{c^sTL#Sb5}l#ppnOvD*^?FUDuN{;eq%_FKF`;}^VsDu!dkUKH4fVA z9FL+*Bv6%%E~}ag?!!AVd<(<4xX?%~@SyasDwQH+vDvnAfqIOa|Mf4qa@3X5p;ISF znP4A;KO4;!Ac>;tP&u~2o`=GWDr7Y(fZ4(>m@VX&*`x}s$$|&~0e+CLLJG_P*lwI> zg!qMF$Q-cI+nuvbav;rJhIERV%jTl|e3N={UW26f7H)IlwT@Uk4ATZPiDXEPCr)_nWoSz>nAw>f zN`YNOMV3{Y3uSi+`eRTqCW9q1f664=#5bNYH)@<()Vxi{;j@1FW}dnM7_gkA4ETry z`2C$;nkD-O0N}fvIy$LF1O`ZMnO!-_@>FI>VXex1n8Qxhc3?P#bV@DYRfuD%%gRm#>wJUz3qqNtr~M@zIY!)l2H})lgsJ2 z8xnzd+>B%A5hpy@?<;>m0rU|)K!r0pI&Ru0pL}w~fBy57z{VXD5EmTQ7_Gr5`)cfP z*$9$0XZKTp*I8F1u3)6z1xQlr$v?RMnfen2uyoL(pbF8urQU={58=VeiLG;Lb8#ZO zTiLFiGW+{UYKe_+Ed4IIQkr)-TjGjginXqk!T|CVRx0N->&N76$ z462aiXsa}e3c^I4S>4DC(Wf9#QQ(Wc!9yl0@6$ z^j47gMgfyRu*QDqhBX1Sw?r=-^9g!2HhTmf@HZ=$S5{~i8$q}?Y|ad|;b9WprN{W9 z**`2ryIc&*IKcgr5A>dlfS2`8dWHnI?(~H{2XSt3x@izg*o>1x4-(?T-a3j z$p%PM1}1P|Xp#VDy;!OXq-^I#%+$Qr4`Z)GG!@?9R@-MJg12&1_E=X zx^PQHEwXs+tB`HT$yr>>k=rf)c$q*n3p+YkEsmvExt|GhQo9Z6lwGoQ(|TFHV5Thi z`76&e21$C~OH|e~S3nRVEWnT+zbGj(^;vjkind52z6aW(dKb^hz7;6o05dRSbSI5C zNpQo_4{3T}&Tykx!y*u!!6C^JeiDRWtqk?UFjrMoRXU^*CjF*+h{!&FCKUEIHzP7| z@f7w?9m1IvU_G7-95OSo48nHbX6cB5rIUVdz5R9$)Z^Dcx znE|qYgqK?I=o@Y#KVTqf2zSvxAv#%?QzDs=nuG?0NNw?M_Xn>(;aECjviY2zeU=S8 z|J(~7e)!>i9^mXaO~5W`=o&lr1?!71-q$3)Q6hL0r^YVC2ZcRvSv}~m7l#N`*Wqe? zKr*Yo9`<3QCyHvxTGepV33Dlyw6rv}K3Kv_V9aB6&DA!2pMQk{02PX^mtA)8JWMQWk!&OYfEQ+>ZXIpdAK}r*^zlK+V$d_z8op9~Ez$p?60w<`dW$?=Up4r<%EQLQ1=W^~xh1{m)m5)1XLsLtb4ku=C= zBj*f_+}wf&YKBDD08@hU+)ewXtIs|6U%BX#OJKv;1Px0owB_MxR3YM2wa~l2xT0R= z?9M5whZC9;st#o6g-VtVZ}kAhW-PG9!#AhYK}xlIcaE$_mYj)i{da!@X?pf~5**hU z)2T=}d@?6DX@SO#S)>yT4X_;dMF+*TcwN#6PXfuZdZhi=@oi`npxqO@s~nwRqp1%#00< z(!5okvqV z*u^>_AS8nA6W!h|!7yvEqD}AFyFtHD{C-D5oLP?mqircBHudN~Y+Nn1~k{lb2t2iV<( zH55?Gd-dzr*NL!k3@oEUWLXTA&{)|d5}Cz%_8lk-=1h?cNFf{47_z_CkM3?~z)@_V zn#c3KS0{JJ1HuZFYwqPbJB%utjXdf8}c z->bhgYSK~ypoP`JSA@2{6iyj%z5!aq1_aVyn_H=z+~N__w@F;E#6<)kH8dXtkQFzk z#Gajt;Q&+8n#$OF@0DSQj5B@4Ecw?hH_77M9Eoe$4pQGP;JD_)hise|Om3?Aff*Bh%07F%euHc3qzYChV!dda2W=LZW)j@iBc&V^1Yz?%Un z&MMgLLYa1ZM8|Fy*{osq1|*lD9JER$vzm3&wF002^IP zb&1sO+A3=o&s9e}{LsU&tAYBWd2{Uy*mu%XnVD6T^qHdoN*#c09+E?Bhi&dYNM4AA z8MBfG$aDsQGcCTuUKaq%fjr=aJGUY|=MtI!(>IcZnHx(aV&x{Fv*-~F+hq<=l3X1w z=z3&H^c~ zyQ;EMw>c}j6gvym31p=IfANmS|NoJ`BmRg2?02N)%-zY;a zxY|bb0SgfQ z#=}1qqdgj4`v22`2^DxHJ!WkRLgOAfFnb$jzI4V2s3{g#VXiEh{j<8*efK{A8{Lu8 zrd3N!?jU6bL!tDR70xV0I`xctsRe+_E1-dTl@!8kfwL_W%nnRO$czD|D4{kWxI0t+ z)|MAY?$!;mV!hVWSPezen}+J(>0r{}@} zi;HU4crI@P=P|zWTMCd;jGf4I!Oq$;abv>KchFEUtPrWGcS%y138_~hMaQhwfJsV2 zLxX$qVwfZyFlS&jc!Ak(FMj5JBRwz=Q!SA6;leK*jQ?L+9W2?!@gHNkV%_?6_SUUh zn;BkE0h0K2x1eh@!2y;U+yJfa?82PwZ0eUDIIvA{yMY-rl0Ide+ z_^$XII|Ca#!;CU`48~o6OdTR&gd=llMDupiP?9e@ z5ar>6mmX2acI`7%&hC4jay|=*YJ`xA{xBgz--Bk^AKGLcz;iK7AM>}AOBg2hX)#tw z0q_m80#xJrG((|x5l!tVwuz5RkQ;Bh3Gw|0$fuuuB9A=!IAs05N^68y^G|9f?w}Z) zgL-yi?oR-ZagXSMFT(^KY&;49Q5p;eK@4%wi>hb-y$|n^gy0Myz*znS=XR&tU`N)t z$o73+-8KEYh0wCC!*1ftlY%FoEP$8vBSCawt=fDV(xkPnR&N9iVYjO)!2|X@+c@rT z6~>(}S4!62Dk-i(#v(emArBNC++clxwuVedNKz%^#1$ryO7FrE($NE z5&zK3`o4Q9K>8dtjo|ENge1Vr3@72-k?Ys3vA1sB#^itsQ4jG79R~}bDOm<5H9u=G z!j5fozV_HHhP)ly<;rWW8~w~PPkn^*;HL@wx)xc&`z)u+n&`wi>h^KLlU^U!BPqQ# z?9csldRsLJjqrt-bQ`NR0c(qv8nE#?ta$+|TRjIfFMDW!IYT|-_6A~)(}umUS+A=r zl?Btjk=t*(U6>;J$VIybCB$Slj)ppJ5b&}N`JCz(?(~)8P65@=UVi!IwE(=^Hf`G2 z1b`P)bqsK*n<%8bHS4PssG?az>x?e4VbN6SnA!}zB@i|B|IS5^`wN_0H}LijHsn8Q z#@^oK8Eyf9*|*py5VZuj5-`v&P)zYnqz!C&os|0S$(3a=dEmlw)$NZ;i!Qw+x=|XW zz5#Gn0}f#pRq#49CMz`vx|^9(Et~e#A;C<50>2SKz!AVJ#HWarqLOJ4dnYz-EDt^W zi1h0}KtB55eIx{WPml~iI`zL$ToH`~nsTIECWGVzSu=Gspze7t(*~=4jOS4s(V88U{vftUUxqT=V{Urq|Z3$eEmGXZgPRux!-6~NSl5MxCfmPyWL>IR4{cMIJctSj%W+jvJK8NC778pIHf-pN(bv9&85Q=?Qv|?Rg#;# zSys&ZStd_>Yk#e#_qsrWV;UjrO9*UX{8f|%17>50&49*;XJd;zLixvA%@LmI)Yzp_ zj)^`5b)L6rwKRvcEEGYZ4Wup$hIhfPnzg^L$2ZF0%5VJ@VdhY((;qBTTVjZ%te4Hksh zYID}PvSHP7vDYGCMhKjqF-{%aMo!2RpXN7FGBETU$OLN$7E?s91c${-2c~x} z&X&nY*I5f`@797cX&MI& zaD0e_1t8uy&Sw27GfZf6;L$Hy<>^IigL$p4Z&19~{mRGY z%;SS7|HQK?yIp`?*zKMh-Ll8s?x1LQt=(lZ6OLXJ#>5)Kz8EXMjuaqikItLJOR z=Hp*_Nv;?^T;dR7i4zhB!i&*(0U8H@U9>(778M9BmYa`=3y|oRBC~@7(m@lDt=Rzx zjpx=OVgsGfDv_@{d*d2ejtpq?e*Rj$O{4aZ=3-W74hhFB&>}T3dw};D%pB@4JECd; zaT2jb+dN-6))e3@9Gx8Xu7hN%c5j|^y7X%C4~>?3WLJx^LNy!+zzas=3Bd2p%v{5V znD2QK_7|@-(zDCA`im4W<2>6l&pZ=>L3i4yE3fQ4{)HE8F|n~`PCh8fpqjlL{cFLx zVq}K$7h7e4r{WswI%mSbou9XL7->D})hC_lZ8J>P&=^Q= zT;j0R%hs&5{7D)$YNXbOesFMOyQXuk9s^%_9cT=*2uk@1_h!qM%%!q&E~ADac}??l zwWgH#FuH;d5@k`Eg>Hmg7ganqSDipSO|7f1oG=OiNT~2+xZ$jiKbUykgAe~(9~~8= zG?D%=$)Z0(QDv35O(D{xMF;g<4JG@;0y|HLRZiG*o;f$tXi7Z@O|b|`nbw#JTLWyV zjY-WVDK1qKD~qLK*EX5;%|~i!*{+lHy=auAx9=w5Fn4gm$A_j8dN`&BK!}E*gR&gb z-p%{!q*;u=G>HvDI6{j8zI0qw;1^??3D~1o-+q$Osk6+OK2t6mF-%r`_o=jmnL|KQ z3o*mixE}q#4t&D|9t+0{H3_D}{;_BcHkf7jyKQvPGu2tb+~KWy-CMBh+i4JJ&ORCJ zdH-p^tEb&AIzvEMhtBU=8n=*Ao!;fgRV5;iuvVC8fWarmPB{X^du;=wN!FwD5@6o(f z7!n6&XQg?YBzxIxneq8}l_r>{H|;$X;Y<<`GdED|Fpp?}Dgl{F(4g`9cu@p1Q};m< zTih1E{f=~(*YcIWMgg`b&TFalc9zl41`@IKb_o3f=fT=Ki4F@y1P$N<=zsJG2~b*A zs{e6{QbEm92dkR$Z24Ayl>+QeTx>~cX&Dba^w1QfAC5=dUYo^YF+1srg^HpXP$_KU ze_gvr%56xl=BRW`digQq>R)HNI`=rQ|B8jbcp2#F=A3pYT}dlWvZ4e1%@+6DrA=e;^2>2307|xsgiQIhiza;#SkYog{TnKCppeaLL5RvZMxkEN*W=YnP zneyZRKHGoKagRSCJ$v?2-wy-3ypEC-vx3000JIDC?BcPz_g}!baY88oAfY59Bd;I% z>*pVQUbkaMjz0h|YKmz=bP^Y4kqroc#qq3BVyfzRMLC-#xp7knSN!m-s8e4#<`f{1 z)TE_EGMXgThSYb;dkD6^rtkzvePg9vu~e@vS9j{;uU@9Ck^bfv|GzY?0>F}cWu)WJ@h*+g|d%Ae_qJoZRc zrR^uvrzryBlQ z4ap)Zpggi*kg=N3un3>@NbL#nuf3*Jc5GZFOOYJn$4T$<@x`2&F0BV;h&du&9DV@^ zWKD@N4BR2nB{Sl}0mNJT>>8?I^~W|u+F`!WKTiQS+7<%LNGYVdEV1z^s1F1P$HXQk zTv;@F>%+Zm+jhf>l`G1SSYavR%<^!b^omsYiv|51(G%toys^oT&fC8Iy&2P|>-(R7 zK0&JrJ%%jK=y#ZGAXeqV4Fyt)Sg|I3js5HQo;S^(@q@i*|DoqDm^ozuj|T%i-N7zi z6U|kl*NAia_6Z$*+uinE#Z{&^o_$c#GWtqFa+>Velf&br``PCJ)MCmEDK6*BoKSmH z1@kgB)wR$#tw%_s8S)q%Ts-BLhhCJhkU)9*fqzNs)-6@y3QZEM@nP?AUiL(%T@L3? zyWNntZ6kl)<~ioiu6H$!U?w) zf|$V2aOpQ&c(VX&x?~{fk+Z5q_MtybeDi6w^cy@}I`)=7hK8z4zaNbTLNS z^g0g_pyI`jbY6C9J@KrX13a*j=XqIuf3{ti5Z#JWUZ-+mYcN#mjR;lNzHv%r>B~Dd zW!;1^Kw&;!`=2QP7~su7CJx%~VU9TNM_GSHN5sZA47<72@8rRaOF&vb^#7YjV|PkZG=es|Mh39Ol`7zjwtaWG zY%Zu)M&t&>%eBBGTE_+gl>>v|*TL~AJ8O+Boc^sWp7W!+Zc3*f5}wjr9Pn1OV>VZV zr%;kyKBJmM$vZbW_78XZUs3gUNE^|`bngu4Kj?nV9i`$s+~;Og!?-YXNo(rN-rlXc~3)?>~Ia^y8Nw)}GV6-1R; zX9CzIBcP2lX?D|f*Ipxylauwm2Mv>XQzpvNncvGL*WHd#Vw!n*Yc1t9q&Aq;BjOB; z9bVu&^YUcT(xvjr2k*)Jx%1Ti0mE((NXjKHHC-YhN!qkn%#~Z76Wc>ilH}#)1 zZTP1EFH9L!+ByG5Z8P5Ti)$=pNaLf^5o*xvfDMI&Bia7{LKdv016IvSouwfYGztu& ztVna&UMXC&K=O9v$Y6w_di1eJq)XS%>f*H1W#wpr?cvO3bHfy&461_)DaNqs2bH(M zf@@<|W`y*K#s?)xSg>K$Jo)j%S7gs_rPhg&K%y_NjwK$-X`#;5?Ql$txW#mdkl1MX!|V) zV>I?TY1OH_M8qXQtqIdAc!xJYYE%qK5ldKjgjyf*gKP-{BF0*PB7@XdSLiow&4onX z_+(sa%m3}!wr)3$U_bF`LXJql*k4T*_~%9Mp*D;j1E8w+Zc zhkkNeQ}qz#h52ySZK8oKj+p3vV2=voaP0M!V?%+1$MfIP)k9 zp!ml(7N>t0GO@rQ9J6HPxmQ4!ZG~#|Kl?`BYx~y6k^<=TsF2!nl?qi7lA56Y*(vp~ zbqi4F!bRylrauKmMaDPZd0T=bBIZ?=l<*96J{6?V)1cIj<^G2sdH}iBL)^Q{N<{A;EM5B!kuTnRO}=>hd0Dq6Q(hSVl7xnZ%8uG543s;(U&Y_BK5S1g@R;(|@r&3d@mBJp59=J;#y)s$xcu9=#gj z;R?5I-5L$R%Si_(9}*Fa)YCAGx1rKPBVwgp$8NHA)vpqb>|A!3DXg{#J~Zb z5?tUX03Hb0aE+{8HL`bKtu#*zmgEE^uz)1kK*>EK-!N%alayq6>($p}K;K?6Y{W<@ z`S~kpdsZ(ANogx~gng_7-qEv7z%0QI;7gyPztgF4E^_|)*+NoUG)^nt``_)G*5Ce5 znKq~naTK+3EDzxT=s=Xm?u{~fzGI3{c2^;giU}N+AfPsjpU;)F2R2Mg+jT;@r^2%yu)s_<3fI+tc z#^r7RT&e}k2+U5wUrlkItXnigCOk7%W>5KA0%DV-DGbXKy7t8sIz{ZJATfZUFo-lQ z+$hyW)E;bMMBt!~@~2)&o#Fd9rW8OuThNJjZCEXlMu%K5@;1@Iwi>YmrCmxGvaF#U zfpH+Ms%z8cjr#ZAeSgPipM3K8L2+V_>EoOM7gK#5?@3k4ufNQg9yol&B0&!) zl<4tb)Syv@BO1|Z}=bm*~1Fgm~&}u8l5D^(EL9qXu@dNbJD4jcZl9kJs$Xeh!N!*ZEc0e#w1jlXCLe$Bru6UGO)kFV zQgyu}16~}C)2a|7bVp&WY+1cXmM{Fp&}Gb%E>m!1+oDa#iLTl6vfh0YL`BIH_Cec7 zItBIZ(4j-qv(7q81H2f3Oi*3sm()lZ^5R+nimDJjXx)m1l91jOq5iCp$e^m!;G`sS zxPx@_iTnSlro zjF%k-N7Z2bZl*RHeVgG>>i|-BBin0HNiCvAq28^CBt^j<+5;0;7|mvB*{Y3Pb=B3# z%xINwznmz0H!PPlm^3*pLE@r=EADT=c&Qm>{PkK=Ibfa0f^IU4zgfE0ZOxv$Y3I%z zy&;_5d4l-_8Pka@tWi3xNNBUx69Qr9TB8qe8k|79=yXat3kGbUgqC2D-1U$`0I4+# z%7TAeST#(s>0e(Z_C4DW={} zFd;S~f&xYQXl7ypb0{g?Cu^5Xlh0py5UDufu!b3OhYLoD9vM|!W@JhM$c4lnMH~V9{W>x}ERipP~TU6gs>U694i|E2Ph;8{x?sCY6wGrG}U##G>H~ z75^BWa8q^`XDN$^43nu?iBD=O zmLO)-LSh_bc67sx2eB^1!YiXMFr6u3uik8gq_#v#x2~3?8?R8(A_ahs0D2Ti=IP*f zHiY%d%Yo1x#TnAbmD1}n{obWBUn(oeX@_0p@nqA7vS{q`mE%AG(wRJpL*TrH3l|O? zGiHpA8TaUX=!Z5Fi}>PsmG#IsVU{MXI;uyoRaJ;C5NU=f!DDTyvVX(7!?!+;6kvrB z-fB8vViQVv`3=GVR0Yimm{^z&s1{>@m=H5QAu>VY+M&_fZU0MGmF26 zZSOhfiMeqzXskma6($nGu?HH+Z>Yi6^8a;m{tjueu1<80(AZRC!dZRaC|^3K?Yw`0 zPn=M|>kU4fqz}43x>ehDwU$7;!=ZzNycQV&E@MjMP7;zYAE_u{3{Z^7wfG}M2H@l; zB(YX_2pW+_qAs6=~>!(iA` zX4jWiHDIuHOMt~Jk^TnzuB{tQU%vUIe%YcqlW@+J0J}VwVAreK=l3(ADDaY!lJan$ zKE09$3_PC}AD{yUGDyVfEK5*ohLpwzz1TU3&M@}hW2ITkcJRcHg4PO=8aU~u6df&> zf*x5y$P?ss=zKi6&ZTU52~FyOqsIts$|CMJ+cVk}MfRuasuJ28bJ`3+4I%*vmlF&%uOGibg<_ z2sTJUaINX`jrbnkMnE!qoAYnq$M@|xQUFeaYMQKS7xzKia#bjMT!~L?ikUD>Uof!8 zgusps#YK@kjw&iDF~0N82d==tK!ti?Z*-)7%wv7!_bH%Ms+kKH7DYuxopb+vV}I@5 zIm3ACt#_HG{4_&fT2$x=v>5C`RzJI~ve3DB>Lkk}5IFo9!1D_C?v(u8TzMJ}C>IX7P+FuVOJamo;zRu; zG29}FkpU7P9sucHfJBA_NI1e%)x*ohskCV1NNm<_NO-lh#MS`DWo7vtUZvEVbm01$gm<0NxtsfUprKv*BqeiVtc=*mrQD#9Ha5Tn>W+W^3V1JC4Ke zO+1)TakYbwKVI8fZ#Z68Kj^x{h7D8SQk%4T!PKO=f4$yfhqP92(;vOyj6|-3L<7+r zkn8~+m0%U5w-oOb=h|On^_-vO`q86hI~+F#T`(9X36S7HWo>};j2&6Zw z>cZ-IUAuPe;>O0Rs;W)gm^W|U(Kk|_;45AVD9~F}RJ0X4&OsTv;OEb$JagB`n%5t> z!T96HFPWxKeAV>qJ=Ypu8h6j)#Prs*^&O9ee2L4MMt3$_nghtBNt52W_uhMTJ$v@# zcOCf?3u6>>P}D>6vvFOfbZU;2rS03R*6XBG3MS$VM|JR`)R&N?SJXC0ep!tI%QR~+ zVj+?D73}4uB{i*yS|8LGJm0ky1IqK>h}P)N-?NJkRK9!Vyq(h@y~0>HXQI*QYN$;+ z?{b1&&80je^y&%c*DdnUzaN$jD}I$t-@PfieR<+fvkDx`P-q0=W(brhpfrJHxpfX`oA3*z zkw+*L0FtlZS3S~n*~1bVo6}llyvRen*zgFa9rIl$1OWX&0>AL~2Bd`Jk26u^{D|ac zm(}_OI~yE&z)ie82zIoE$D83`LH(Z1U_}MOgkg8KtepIbWUpT*6W)AFUVVLnq^71| z#sWJxFn%LuFx3v7tlUyAi`ExOVT}Vom!Q=l^?=I;q}Q}n6w0ix-;+njTqyHrOqR5+ z{iOZnw~7Ht32GtEuTdFN;M{@gV&V!uF=sZua`IAu)#FlNmmQRV7jt7|hN{`QL0WYi zqH@bO*c=j#L4dK9Y0l?f(&zvHKmbWZK~&&TV#(;xQ zlS1@_ld4UMqs4`gqQ2FH57v!2-?w6oItFo(Qq8v)})L_T~ z(YxSc_#(wHA*n`qA{{_8haLrUpyIBtBSwPngT-I1f3LZFSzbK?mgnT<^4MQ$Z1pMT zpqS@YPkLS!eeh_2*h{5FkAXMhw@A@6dM9Lz@jUpMzVgy~{`>_C1QT`$Z&}v_C8!W; zvcTt@5CFv`YLgphRXKz`089i?q@It{olY#WrA5D?vK{Hh zpS*pzO#b9GDJ$BI(5e>HGqgB3*5ap^iaN6_&Ms34ehO+~Isu^`BNo|U|C^( zPJaIRXTeXh`p1c4&RZ`AjG-n-ixE3r0c}o^*lsBG)npW^6&*%HHJMV9VO-zkHr1Of z&XDA$7ly&@fY=ZxDBgG2iN|<{w}Twx%l_tax_KVsWdG*vUa-U^fmkNDkuQ(gfQrBQ zo5TO;3&{)0U^Zf{FNe5&p{)94GCY*K$l}Gn$}LE(X$?RG22_|IjMj9p>&=B!ckY@! zlDVf+900!-+NLp(B&5H3B$&uuw^-hM^hWvQwI?O9d27s&;I-JYE5dVxL82>C4@s^c zp4AWFS%vnXy)mTH1XI3p@=|~kP4aGSP-m-wi3uFmSemqG51~E=cS!4_Jmw5Mmdt}I zs9Ct4#}8jQCKOPTT9}3q%<89oH)%K4A7i-_3*-CEz{0}cm4s7$JF`B_cwO5?7hTkE z+qP|wfB*gW?zFTtqsn+jLtIZG`=WZWw0Ix()JosJ{nRfUfHcJ7J@UZX17#rHtyk(% zIs_|2G7fI_b+TgB3K=q>zxeyZV;@E91_#dfZgFU3sjI4zwHv58*J4!HSM7VSakq0j z7Ok4IY{AR7No8qqB!0V`2cR5yc9y?%vOO7imZ*q<1AQ}kfg8r|hq{KLR z@?=H?SgsBxQudW&K>;@gVS-uGlhr~d=UvDn$QRE@u*=Ltcz4^Kcix$Vw)ej`-k2Z& zzVPP*{7?Xd!U2s>B1;F*|(~JkPV!lDlM9CbrLl zgYR8?vQ|KI=69LrH`e#zqoC(U-|CoBK=G>a6!KJ6~q2B!{&Fu-HQ*CA32i zX?MZp$RE%kmakoHn) zi>LyUl9C4P`2_jmi!WqrR;Dcf-+N-(y;(vWwaN#^4xp>q_mUH7t&M~^z>TyCHeF=Y zSd7Uzc$=Z#;BOCW(l$M+QS!Y!9(?e)n?N1!)~)v#B}YVb?)iv>$I@vG(*e9N7O(L$ zNkiKYl8Z82E}9dVwncElBoY>c8`I~mm!*?GlXfjy%8HfC<(6A-Rsq)?FitX}5*?80 zW+5H$&#=|qP}qQYx`;oAKRwJEtbVBAx^h`K^((pal5Pmv{(_{!e4*p0JH?&QLaGf2 zGX{Gn1CTKTva>KmnTyYc#-zESK{bvFCK&dWlbZsJk3mTYC4Wpb389iO}SmHnA#9iHL#E4-wY|OofGBQ=F)!H z_0qb}5ScmcTe&3l@Jvlh?k>Hf3k#z>M-RPoRfkpE?H1hrN^0Y%C zu_*P`V__5qhAgt{5P<0S6%9I%YGF=51NKR3`lU26_8GcS(3cs&pE9m4vtIBn_x^dOeykkl-Nz zZs||Rr(zW%%bF6^gOgyNVhaFJyuPoT%oKoC8afsyDGoF^LxWBBX0MWN=M7Pzn{1dM z#UKL_gLN|wrKdjK$Wp|YTH<*#r4l@u-_rMNr!)naEI>)MhYT4qwQt|P&2PW`c8m`? zlQLyM+f?mxKeGY^M21sGEs*(z24*PK!L_>AsAfe+0bY7lk7FSV6)9(JQ7x9KMDj(=F5yZ3UWEuN+( zJSO-u(Yeu&(H!)CvSw!`fbTBkC#XV?2J&G<2uze(w`w7ufAf{R{m#3xF>|Rb`|>R@ z?aL9Xl3l>diC78uW;3z_eoGYcdg&{z~pQcM$D5CAY}eE!ZYa>a;CkX?!C(J`?*h^eaM31-!q z7-_&8E9z{ruawalI3Q`iXb{;2d)zX0AB#Utdp!5UB=OKflQKw~-Su_#hBd3`TPVLA zdJMj+aSm&adERmF2#5K09WM$1FsMuS>(y(?$`#9G&)$4(($0!U2}e9$D7MgU+!7U= zp!U_3mm*>Znj+efc9h!f`#23KfKd(D2I53$t!Xz~8yq8{9ecsdVWi}2S|d;2bG5wp z;-j)>%NhxU^wEhZSTJ&s03g;DzzG=|aHtXx zzD%E+B}RL#xT%3cTcaS8_PvbUV8*>E#5}ZZ5&UAzHC7t^B_J{F#!!(C9sz)N5`D~T z;Bd}%jBeo#H4zq_`dC2YCdO)mAHtp<#F;(!VHcz1lru|$-+C};E^dO|`bsfuUoM$& zObbSg+{KHR$Q4&yjwAu7LK`Hqa6&7tw<}xSMO!PB!LhF080i>3|8Mc{LV| z@495~t{n9}F{!a<|Nci)-w*k4mzI?1zyJD+;%3d_|H#Ij)@fXPZ>?70TtnwN-rF-}8vK4J-$iP9e5+Pw_^HMQX7D9WV@sI%65i@jIHB2msvkvDh z9Ct~3*TL}uyatAv2tbN=Ytv?<>a4*q84&tg99GD9^_T&$ zQ0>C406bN2O`+7TpD(Ky&6B(De^9a!V7*(nvy?=GvlTtk{^k``%RESRH^U&?0{bM! z$fe=78R2y*^LNS*AH66~-F2mu7VeU^=U*m)9r{Q^NE{5cL1-Ln!VH5Z6f6#aY{e=clbKhS6sT87{O|`^9Gto3XT^)O{beB84 zES9Gbz%Yd4?&3Ot@aD--O(B~BZtG^Lh&ekAlJOH#%OU_8#f&aokKrj$KKNW z0K+=`)W5uk4C~kzPm+nmw3d(ffgts;-9>0Gz{|r6dnZ9EOna3Y&x+t0{>3@44S7>G zBe43{UwtkAedce9;b_7@pVH+yB{D0kSgPy>2|xwV*-Qs1un85Ky=bc32B)-d zKYBybI`x!{5x0o0Q46sf{4lgIrX`p?6IjrU0!*J!m$M&VIejPqV;8&(qBC%4hcqK^ z{c>s7wT}eCJK65ANd!amU?%E@@tQ|{?DE*}E~m5?C$qyHsmY!`MDo4KKS2SuD@ROB z%-zMs#g8T=Bsd2S9B8;~*k!_mCv?2^fXn^QMhJ?As=nvv@0G3@?O>MUcbGYYb^?x7 z%@=Ecoa&l7L}#dn)CG7NyiU6o*5ISHb#=02*)l|g7^32p|50;S-ru;v`t=kX$}H_( zs+0Nph=&*_(TdEEW${wfufqmEdPwW&Si}K8I@F5s7R?0XWm>c5>Ocp=RcVtaUv(;i zoZ=s>MQVeTsU~_oZG2&rfG*B8ng_Mo0KRr;lZ??xlF;h{N$+!^%%1Xv+&QARtoY?S zBqgbYMgXb35WCxivC~ZRyx(2u2rH@IJ@OIrE=Rxz_bB~LL=y(8LqX3~p zUeGfzt;Nt9|4_Hv?gFJ5sF*KL#II%KV5OMAglSH|Y-fSCS~2EskflF-F8*PGvU+u< z3>!X7V7Y)9DNPv6QU=Ggg@~)WdPfaTMxbR51^_Jqh^tzG+~8lo^Q=63?=|9&7;kNd zUMnH3yGcV}1OhYDmIRR;_Ro4y_t@rwe-At&seR>ipa2JUPGb~@Z-5hdgI&^EbripV zAjBYaN^}S&Kk69b0@V$4t5>h)t1t4rKbwWG_$Y8JDL^T%9m{nH0rnEs?zi85TaPeO zs;zzb<(KMSUi)43g$LnRuR?I|o;}jOLkIQKq0-&`$3u9a^8n<%Werk?I|A>JQ>yDw z)v2RK3lqOh%YKowx^;)P!$NyHCFN6~*mE(0Z|-Llh_bSB<4;K0jxxvdvrkIkA;d|x zVpU5>gk|xhiJwVPNf8kaq-|_wP6>pBHvmSKV1p8qr~zJQMG@c-_G!HEBzqm-rYVI537%_$wF!(}&0L~@$E^w@3k-ZS^e-i^zY zv{$DC@P%d_mZq|`piXA2-YdC9HJG4-kKh_k%%BDi8Ynxq<;Zo{UMDN2eJ8H1tHjz+ ziODs@PWYY7!VbQ}qJ>ZdAHtuTxeZ)yV~xS$3~Zd*BS>T@7?Fa9>fmGeam)elxN+kY z6O3uu=0Q_zBbX@|9eRpVL2@&}Eo9t0Knqy`90Eql*@Fot40YK{5QSlyj2wBDY+k!j zI&^5S#O6r$jqp1r*?WLte`gKyPWANp5P%Rn*|qNIbA5g`bBeN(-FHTlT>1AQw;n@Wm^-9 zn3OC$hJ6lMiHr*tF66fr+>dfxW|-QgeV=C_1!yo%uzP9KrcFQGzJ0sA`|i804jnq^ zTC`{(;G1&){rAhdb?cO*jf2R+MVT64AHi-I9Cisre-H3-5FtQqK!Tk-3`*2LGWDk# zSjhMA&jbYZWhLqsp&`h3q{`tuP~BH`5^?U{l_%4t{+x|_Z}6Pp>mwdQoMbCiFJrE| zjrCNvXZJ3S^K_U;-6M{@#UNo;Xhk8N3l5J_!k&`dJ84Xb19&J8^p#Ve0-U;PeVXGT zF%b8#hUv&g!6PR)Zh%k&oL^n8T5*I%Nn)>yk*V!sS%QdI_gyzs7EJkAoDCJgS^>~1 z>BSF$0IHn^nZ2P%*5(weG1dU{1qKmFPD_#3k?r=`=bo3fzs{BN)eFS00!eZJdU;<9 z;{H;=`G4$P1%Or6)?T+~?sON^G()$9LkK3KD0Uz!wqoZquzvN~zGuf%Y-~{kq`P70 znt%yrV7hMp-?z^_!%**mf}-3F`<^o=_t|^xwZFag3ffIk0?iUp2+DFfVZ~+zJtlVT z^MJ4J$uAFNO1_i7Wy3NYwUiB?k_5c)%#a-Yp@65e<7dMbjDc8be-W)vq*j- zDj#6iTmcdJ;vZ%0vIX+|KVOiy-+WV&lL3}#n1+gC#Iwa4OJOlsCUp?Wn^576WZDq7 zR~BuR&;LC^p1S=qX~glaBQF(O%g$134FSXVH8eRL&$N zJOC>Kb_&~cb|4-Y4q-5#yafvLn|(Fq=lUle$sDUMCfKDhKlrO0|gRsHwOE0}t z6L;Xmm@#A2yCLnBI=Bj>>el|M4HUn^qXQ;w;GG%>RrfUiQPN;YV(6V=cXfm8sX{1F zGu$#l%wvLUAr5yA4s?hXSye+dT#-(lI;!oVp6LVDp0(@N@w%D#o5%=!-Jg!r8X)g7 zJonslWPEEkZ`Jg8ISjIm1L5f-5_;ft%@`UMDklv;TS^d6zyR9@we;-ge8*|C9=&4i z-^An_P8f1KG3jYE1&JlCt#li8l_a<8F8_M^K6zupEwTqO5G+^;QqkA|Tg`~bwm7#& zX00xfY6lc0p!dtL#6iJvU%MqDVp)A7>c3dKp7H>ABVAN5 zQduK_F2m2!S6d_AY()hJl@-cnxV6~6El)nflHM)jZ`Ep1||| z&`pxGzA7S&HC$ z)g`}&lJ06mOHl$$^vmlIw;qfZYu9wqNFEFcg9O-M>i|GpS*A&NZ5YH3l~@LVZ!fI+ zjlcZz3on~`sB8VlkENzm%lHci$=ZceB>l)4sWys0m3tcFg^@jjGv~& z*nsmk9I+dmVkyg)rQf_KH4Sz0>-1k`^aU3v0XFq@O;)Rv);VR`nj+Z&ql+MbT^E=6 zpfeI+Xq08sCc&@nxl-?`SK@bjrvc&$iWCck;8rquyn`;*{prN40kUmcCVQc$=+56D zEn$spMsy+S??#4LHAIUJ<};-<(6|F>fv>hmuKwh&f!|vL3hc(j#B_zq%(S$$G!p=? z3*m#!85tQ0>?&7b7#x_+Ip-X;y$7ldrKP1x%Burhbpk(!0=oKnK8eIzkLBuu-LSle z3J-nvnlUh$p%y0fl~S3zRu=p)QNI7^O?6v*T%3OU0b3vF_M$wd_uhN291@p>zKfJ_ zXvWwAE4%5p?!v+P(0VI%-EK(7@J2B=n{DVWli1GpDL4%eG(?!c6c zo>X)i; zdB+`hn9n@(%zd7#Ea)*fz+;1aJaMAphgfOY=bHcZ2Z5^}Z^^zS0J7mn2SIM%e-%3EiDzUq2AOOV# zoP0~IIZ&rp;Mu_=b=WgSCraz?z3vd(f@f)Ty2 z(djZyPk<(mtV#r-33nx#K{sT{znG2Rldl+pvDb+=n^Z?whFRYRot9Lujozw?3PkXmxT`~l4(oko z^$+HMMx*_G-U(JHj)4OQrsw43%o;p+a9BeFBILkU1B zr*@M2t~vt|mF^cCq9on=;4{*t=Si@>4v?#_zFJ9*37GXV=w;$oKekAd(oFZAqyDbH zkN7I%c-&yZq}m61l-p3gE%`7wL?VPylbZlcgd&3M3Xp_GL`gzMJ1N}0UQAfd*6^+i z8kYnkG%6y^`J4NAZ0Dm{CPX)YlobvH(B5o$VkioZh&8=VxG)QflBn(jBx}%_vSjx6 za?6F;vUbT_2qLM6OT$=D3;aAU-dZgSHE%%YyeN!9mMLjz zw+AMqV3uISq`+*jK()XIt2`q_*G@A;!@UwkRakS;Ll3oE7( zQrX3ucgvCuC1BuWwvY&8SsGrFWf2@2-+tLJS-o_wbUA&rgtX}-E+|*S0Ru$vtZ=Pi z^afJ=7!Br6CuR*WDiw7XD@%63B9$(BV&K}&BcagW4a8CmXO@aa@RPeemzA^@i6RaX z5+H;>`D@_FYXFhcNN&!{FTXr#_Uzen#*ZH#lb)XL*tTt(W$M(a0{^?9!@Z${^*0b$ z@_1NSm^}8_W9smG@4c_2w!pB;jgJ@7IS5l=%}mYg=SRtSf?@{}Fgg^aVYk&hESLE65TAOnp892%UEan8*s>Vus zKt@ODan4m@4v&=yH;&K!lx)TTF=LDkuo@*Nzh36#6iFTKv6{`|gaZOQY!)8* z$3ybUOE1c*`Lm>P!+f#UmO`z@DD|K@8m^f^cScaD%j@-+A=+6N`II=>ORVs#$3*$SyFKf%R0A{es0zDisO6TEui0(ttWr{%_5ZjxYo z5IiwBR4BU!cvM)pzF0PwqT*~pfcY>wg95a>p++Wu`j&kD=5rDrmna$iP8Ba)S5(mI z7*#+#Of3+tX;?M>p#ZI-$?!<59!POZipylN(6=io)4Ymx=-3|a9vQR;vK>ko z_DcjtNS>WLcN*uexc|s)Ue$ zX;KMnXOBvdj;Eg|yK`2`>rdP*gK>(>9M>YK2+hlziTpz9}lmYD%B^W{` zCk)0d;9)o2ax=!`5E*mTSZNP@XKL3+0>a}FD}nCPH~>TD>-L!IOo3i|Li%Y5vaknM zEU0eCu~}0z#?Eg^M*;9=19HxksHnsnf|AmVRfwu)bUQ6JNM&6fo6@Zfc9e@XZ>1~- z*nQ@Srv-X!0JCQ34>dx^%q;Z)AM+8tBd^q{q;HL2%vJ=FaKL}tSMR+Un*MIPjy+(s6DSSvz)$OB zoKmBJ8sy3v&mt1nm+}m!uEgibLjasJGuniEXv?x#AlaZO}yZhi9 zpVZgAVZ#Ojr?~*ToCyBzLFeFa^B+A1H9#pZ)6yS*{84uA-fd1yOjP0_9t;aa-~o)G z^w1g|pTa}pM5t+7bP`YnRt~@=DcevEPa@Jgxot-TZuKuo? z|Gj`0jBq9qcf2hv^%7T5xPT{{tPo2pEn^d+x;SdZl)qjU&z%XW#RM6D*X;`Ia{0~z zhFlLx?V@!%WqTPUy>O4?hS6Fu!e&;M7s)5DJtZ@L{7hQ+87x7Wox~9kro`$2Xastc zq;m^$VoG=YU{_Uy{|7Zd!4&Dk3-2FHk%<{N09|sUL&7oh)Zi{@$mp%C+-+L6Yz4`6 zHLpeTORuzg@c$lW4S*4w!HAvjyz@>7fa>hw!-uz?Fkyn@gAYEiQV;j@&p(&+^z{D< zcJ)_r5=PKVFAi_K@dgHjaWWdwCL_YbWy(*J<(cRHsb4B54L((R^&2e7Fy0M`NtVFS zXw5STmJyY1uL}+uu~bM29pMZ4r5T32brs4rnk2VKZF<(hc6@->FmK*Go}PZNYy8KK z>l#pi_vM#gUVqCiw-f>JCIIl#?Wr0zg8)c^u>4$)Nmxvx26!t93nVqAwbUW97E|*v zR)adn_4oP@!XbK3aAC&;4RF||abyML!gL5Dr5mvjZ0);CCL9W^ne~%Awqb=l z^z0{++`5z0G}d6EZk3X1lgxpn_oS>uiH5*QsdSmlP`$buW3^kZyY6~v1tDip*OSFz z4^wKY(8a;>g2U7ZI|EBx`e?~n^C)<1o+{4o7^5}3_!}z;QVpd@oFV2bLRzGS*IBGi zs~ZX!Fg9y6(q#o^i+L+#*{mt@EugmhBr@Xve=FFM7)$5(HU0v+w>b`35Zw{vhd|=o0 z{rBJ7$BrF4yGxfYS>Jy9ts^fl&wA5MH>uUE5hF&ZNBIEc|9q@Zl|V+094VQZE#*A; zv!pr%!ETRX7s_pqz9P?lI9;y1=LP9H^a6=W?;;im8=TGtsY7NMbqWF0`_K;%re0jg zjB8&H9nDP}*Ged^2no@=m1w$}`xc9!8~1zQVZ!|U^UotTcazIL1)}!7+W*&aS_2#w zjR3n<*skH^3&~BoP||)VhlfGx#sCySSUK%8=yWMwhm~WD&xFKOXP_f9&1j9c`qPP4 z14^(68!UG~vsdqg`!c9zL8q5t%|T&mLjMH>0-M+8NPW&+u|vhdYqY^2*9)J(P9s9_ zIPLMNL9J6_$FS~!Ie!;s{XG(11NGHV26I4%u4Bz%NkIJYZHS{BWp zC67J&nA~&kJrGkHoAfvupxiuveTn3i!9|%BQU`eOwPU?)=Z2;7+ zi4Qhm#tD)~X9CM-EqQVa3OH$7V=xS&l$ZN{2`?(apZ<3Z=wKH>!iI3cGr^3zAUJ~q zQd+AXISr}}n9PHLV?~Rq3Wt*@<)!LFY;3H&`r0e9Xwe+$H*lDQL?wzH`nVPZj(|Ho zNNee98bB5{5&>A6wgJEtRJdWGgn$x0UP(^LzCda>fd2}@ht7h|?}ZluC`U$V#W@J` z)b)3Bb92dVsr0*5yI8Sa->!f27pMWYADe&is#U9ooqO)NY9d6y3lfot5Swh-Q!5eh zQQo3WXOS6`!7Bl2sQW_iAULD$zR~}{YCseHNbZFay$j@qUQ#k2uM^6AV%Xh zIwhcYEOSbG=`u1{R(|uLJTT@odF0<;NZT&`Rj{W3FrlhOv&>joD%o9QBqj*J89~M9 zne4pt&zJAM`C3MdJV)AMWg!S^5_Q&K_|OLldfX;QV362SI$bXL)1Ct6q@E&4kwrV= z#B%?p)Lql%l2nlqLCG1d>MQ|n7LJfN6wZh}xoc$E{8{oS^w91j*u`-Ml(3+e)gmtN z97uL^ch{?EYV~kv7L28p+-0-mt}D(^V7D_I9h(x{NVNw`D-e5|=<^4L~fCC%Ytk=N(Uz^-SW&wEuAh`nT(UW$ zFVD`-rWykT5ncsm|)3>43fm~AQ&OR7dfn<-I&~IgshDT z>Msfk&@UW~jp8lM6MIkyJAwYXeYOOI=N8;=zA{8L z2N!6{9i1s1M_(tw;75;Kf4(e7WHvh_yp#-^Fd?spTiRJ`3Z%3iwgnJAd0=C}`_4Lh zq7Ta40m#ARZNOP5MFHP5JjrnE+sJ{qgppZqm&s2Wg%HKYCa)HV8~#q>)q;?0OTYxxSEmak3zeIo9^I~1Z}w95``duvZw0(YL7)k` zA~VKk4r@dNE3>=NXh#PzmKDh289&RYb4Lk7WLg94Fk}P12NQN+#<+O%F3H8RTcEN! zb}Dxjd8_BiLpMXBYYUc6XJ01X=wt+)fVCdx1vUT`E! zjXR60wpvw3cnqwP5ysGlrQhHHZDQyflwSFBjU3)lJTPCep8uSfs)AG!vbfnD%; z!?ZSS+6;L8_17IR2C^c!guMIiyXxi}Zny!SW?+>JWXi$dw)kEcLklNPpq}+#1lvRQLur!1ES(j3YQk;s%@v(3>g$eBcII z`pYB1rD~sWVwjQ1uI1#6$mqdBxm@#teEw{?*1vABxk1)j05jJ@p z#zp{NOJoWq2#6pBMy9mPkNlf|6W|5YR~$4d&VF%FT#5-EbDcJrp#@fy$dVsEmh|*A zdFjO$B_uoo%WGi3dFfBt#Jvl(m>aBa4H!bs97HC zfEUsZS-EoM7F@W)S26wp{clYnzwhI8u*;_aj84TSn`#UQ39JZ<(a4^C_E~xS@yCS{ zRD#LhEZuD?D(D%2)c~GogfXxY(q1E&A+WBt&*KWv8ltKXe;JZS*dEd+Ze;wa7zyVWV0$%P55$$FBL#QSJFe10x z5Rnpq*McyyscpMR^^RQSKFWaA1yYeV;`+zkVkN%s5Ud;| z%8QSUmsN9ql2E9$a#hL*j#*spkwu#rQP%*0C=H*_tgXSK{sV+LgH81XIW9+X>DQA_=a174*1hDP`h7-(}kBQ2H=k;t!6c8|{; z*+SoC^a<}zf6W@uhs}j^=FGv0E5=dK34@n_C1RCT3tw%8F=UI(w(1ML@b*DAsYP7# zv&Fw=v;Xm>#^?*LSqM4?;xWS$gCPQv-hQV`NL&kf`rd0~%ksHm3$Q?y6{}Vjt86N1 zkmZ|86fZMl66ORpjEatyx8HqFk~7-K(kWkw5%Cy+BaLobh=e4zxDa1u^I=e(t`GY| z56$%s{RngsINlXGB`_{E6EW4?w#FKh1F@0I3iD+8)alZ;U0a}ah^q0?WUM>O>w)BV zs~{7wSCarl-KZ|!F3&%9hwQG|BRxi3s=#hNqDRo_uo759YQe%$oq-WwAjeRZ;_rHg zZkQAG45bisokLw9EP#l`iSU@v0m|&sPXdD?mC;ZjoMYQ)CC}?Lci~+8%#iFIED@v= z@WN-Sf!~6ptk$qquRGX1{$s~|4QR6*k(G1j&XwI|WvcNBcsWLgf;Yn893*3u#MDgn zG4<7DSe}NyIQ%w~mb3-u2V^%e4k0;Jfd{ufcO0K72~s~WnAiwO+bfmdd>N3C1>e;dHK~>W$@6!YAKJB1_ShV zOY596XFdI)()1s6rq~O0KZQ@`>AxfD;Pq&Oeds&HwHHy#}&< z-WYsW{etZ5Tc9B?41ET)hH3wX#m? z8?`8I2YV~81-6meS}hoh=@1fLUzxp-UYik8*nR%_=dbd8gAST}fBH9np&EcqkkWfu zwr<_JEtQqZa1jg1+8jT~Zc%&m+z=BBQ5I5d#ct?M(r}G`k=C?p`IkTWYv6EefRkqz zgrAytAY+oA*ZQp0#nLtUuCwuj(!=8TzA z3Eoz>X}Or4HC|gplEiiDeF>if-gGcl$5V$)M+$gN^2Ha_6UxMktGT~g!3@*9+n#S|niSb)C&e|O2cHA|%9F!%&aNRt|L zG|na&x{h3#q3rfbCk|P5{|SE$paw|ukX~^#N2albyOw^|VRf9Cig}g^5-*PgL8XC7 zHzI;$&bxfsatR9yyH1^eyLD`jv_JT6^>6-;H2}+Y3zyCS7DyM<;1~Cl_3PI=I(6z~ zB^}X$IsxK`|M^gT{*zBWDdC8S#&h(!OJ;v86J@wuIwY?wtAfrPiuvDON&HQz9+UFP zyIEk3EVXX#P|AP^})IN<_bj=|;Fe$0Ml@&9?$YJlygT#;RK%{9ZZAHQae(&7SJ z)C5ccHY+Zmrw&u4}y9w2Hr+-g~dzfbH=If zf90ObAo$!N7CJ8g8JZBgVgAP5QdWzgWE4_?ky0;M?b3N-DBNarS!`m8 zj#qU2g@#3O@!_W<8sM`fThV=($QdCCDG}!Ca#zmeuhlc|eegaB3`A&PSlw}Hgsz`f z!vT6pwL=0aT0@sHx*Fxj&pwc43uZ~1{-=sF34V4lg|x!Ugw=}=g>;wlU1ops*TCV{ z03k0;90@S!PN$-@Slt>Ko2-2NS>TjE2zqKvl*m!S@%B6K80XEO=fVD19DY@u^#Ay4 zz*hqVyI28m0{B@#S2J*U2>h5j+O}=0z%DN%IHVi0haY)ZsJDC4Nhhhhk2TO$FChe> zlovG5AUSp7%ucYt5>fvkQcHUDGQ)3uLpuBlhrOQTDHd> zSeC{L2GK76`6axlDu4P-HK4|3(3!8edT7gV8$Zddz|kWd-SQUue}yLXwaa!I6n}7E1g|RZ^_?$l28Hts4BYdy6YqWVbK|6;*S8l zTx!;qn+;Oe;E<|1g!u#?B?vxPQh){h#0rTD6T!{?NgrSkUCs2_XP@zOC**sPd!Ua5 zVawG$u7nUkv9ItUoJq3JFmwNi1|VGTPsgqX*d}bV8_zrMyf=UT`DeNH)?3}sH#c_f z+)3X5-~(x_t(34(J0?OHdm$_^V|h8nXSn8cAgC2d3J=gUB92`_{ZIaT*8qHVDU9cY z)YcfECawFOBC{udF28>D0VvcV4x>dv%x)>#Q!ndwK;;Hpgoc%FtUB0(gXPi3Ca4Ok z+PFg8^fTVB;{`mBovmTg!>zp|0ldohE*_j28Jn1GuH7T6=1wy`G2wBgw?@aoO!NU+ z0lnQtknXx@6%Ru+E}7(QS|QKCA6rCP2MKQ5OFW3PY{7?;Luyi8twPiSopMR09_Ro0 zOVt1+0i4ejMJbIY-je3x4)v{MB^JKubCD9ZJnxHWn)=xkEBqK(QFd^2wj2}P#X}rECG6!=G6#n%0 zs{xW5c^*+8Gue+$pk6Rfw!3xh+O-aZ1WtJDvBws}S933d-EQ5wDakIutnRy(MvwR1 zcb`BCs`Pi8sRZCLe?Vf%k*dIN8xdX2sQ6~{9;Kb_xUQ;t6s-^*1=wb!~S#( zYk;)uiiwFCi0!L%mp6R)aQ8FMJY$+ae?IjeWz3aV%JtWcldW5}N^~eDYnVZ~p%xPp z6RV2Vh?OuK_Pkgj1KBsJHn1^$?AyoD!PU{~U!k4jC_(i_?M`jX z(5~0c`+xr)HK6DPpV9~cr^X_4?7~ok&Yl`{uph}Qk;h9D+jMDhdI-mY-a$E75 ztZ=zwmRo^XRK~hS|thY18|3;sy8^^eDOg}sx)cR zB(=Q~z=1luIuQ1qKIR*}3sluXZyjGoZw&{N#POq<)H(=U1~Ji#j+XSZr~r&G1j4gt z&E_dXyHhUmO!&WNU8TE9WaFl-sR%+b0+Qb+FgZVrATj^|KmbWZK~$WAU=$m04I>nO zgnS3`Daa|vtam*cY{{i(4)8QQ!ZNibIy%~g!Th8PF1TPcq21=+D&8wUJKgVkg zke8Cwn3*(k+Y4sZL7$p|9e+?V2_;48h}@xfk1lCFdJhQCE8gw>VbaH+Kmum@=X1|J z2%sPUyUt#{dMU}S4t6=16WngwwoOTPCrp?i(CbxTSHA|&{lgMJwi*&%_J_ksbp6A` z?@(LzNA@X5SLnHcI?2z!@VxXr?>bp3NyglgYGdc*SZ{PpthaTm48G0_>7WUEzCnA7|uank6Zx2OMhs*fB(ep&o*S{dG!u#{pq*Y z0LOLmu8Xs?vpWqPdJ6X~q))ap+djx{7w|gi)Gv%95ST{h2HV?0YJ!(=gD?Le z0r0}$@zh9ZjX{=gt&qO$qr?h2pr?l*tWG`g_~SC==bwzbc5H{3Kx zDP-O+U&;@kyd&)fo+0j-6a)dlr6`(C-UL7X^!KO%GA(LiYiv-9kjF_630wse!DpJ$ z_GFd}haHOSt*H|O{O*azC5`p9Qd?6aUZ+Db<%Y&aDXpwVYskUl+oDM!{FvWRm)$c+9+OHg0( zfg!^wr<@`&adCH-mXr|ia*#NzPNYA_zddF(z;qbYzDSB+Q*h9nQ@wdMb0NzL6eES_KLHO0hOP0EO z_ULZWb#~Q*@#CWv`Qe8j)FDVZ)s`SaKc`=NY`1(LXc_ON4llitP_0aZ5C?xVrN1UK z7pX-yZ`mxToH7)Bhj(bt;_;cYXLBRbS^Z?TIb2q4EtAg4;RXZ|;z$LLe&}y_vE6R> zFvrEkdEvE!ZDT@R*()k4I+T@_b=a|E$GLRZwr>48&-7{2cdTB$dJC?hS_EAL5D;(q z{PWLCMvord)NVM|l+eBm^r8RFHg2Bvu# zJXoY%`wsHsk3YyipMO!FfR~Y+waaAO?T<@x8oLgB=2z?#Z*7CrRo6%(^eO4Dw-Wn% zDxhb%2XmN4sF1O1hKGqUELh^fmje+=m3$sdRs!w8P%VQR4d~Np4irN`kP>n^AsnOU zCK@PN2?9_aHPZo&a?8YW`qST|1{BW259v=~KkyL;sMH)DFIi_^A~`=yl%KzRPtF;0 zJK7zX0qU?@imN3#+9K((pe@`;n(f}bo4owei^f}Sy-l(@bm$A8=NrEF|L0nwlEYp>xbtV=R>DLe#4)f3X-MYx8$Y4S25^R(Dod#cy6QUtWLe zK1s-IEw+?Qsl$gD4P3a;pb3&3{m0=hi{)BGPP#%_?L^tKY#J^_QZNg4rycbApQ){VOyA1hN4p~wP*NAxEmQ5QOK*9vDO8}=<0dS2<1htfsF+v}Vf8>rk z?vVEF+mm(_4e8hY5nF;4PV`(@-e?4BpcKsu*N*=!aVaqf;GPK~wV}@Af>E(r;ZS{| z8bIdD&ta?lomWxLA;=d8(*B}wroS@eP{!JpRfrN1rzHIhL@coZ65&LbJj%@!(+uUDR*}GgZ@qr>7Hpvo2elh`09NW03YCNA^l~5cVg7^1eGRB+xvCY}UD;u| zvJ2G)@Dy`w3uy-n_rgwrqrwFjUTAp# z{SRErSFA91?%46He2sS;RvjEJ;8mP7Ai#dkrY$-0f6qK)XxpwG5VykW?xEFUwcFqBBtX>QXd#1CNfxjq+04wM9llOW$ME!t^cCqqy|8Ez9B|Y z0NS4c9&BjSAchQd){3E_1};bT$nKJ2*}81*0p%tm&VUqwlD4khx~h=V!NEb&0wJkw z2ysaeN?>Y&MJDNq`yAjo=yG|(2}Vt3O_c|(GUONJNqs}TY|2?Lx7~S%lne<2?JKzY5-6)Kdh)69498)2_QcU65f+894}sb zq(nl$a^9Xs*-%&^{W79;?6LPC*hPJ+x9j!9b2gjJ%Z$l}8|@@Ly7w@^g`2sy zwl)Mg3lZJ2APqie^XARMu(wc+*bP9u9gijuUWZIw;VsB{$mPiU(*+JGC-f$OXd{+4 z+17e{>-+lO>e|2a5BiY$Jb>MikHTGEa&od0?Lyaj`+c@=>;``&KQ&uz0^M~Ayhnq5TNzg9~E6; zpPiVTgI{#QH0%Mj_18JTHX`O@dx2u`%OemnfhLt2BXqHw(%}GJ&JNvJ zy6U*Qyu26hhKmzz#t5SJKnei+G})3{gO7q_4`OR}f+fFxFI#d}OS_ZL5{Ya9Zw)w$ zZ)JE({72z6Qq{WMK4tR%@u$@Qh*Hs_rgzI>kmRXQ0^1Gy)VJc+gqb*bC{-8&Jcu|2 z$!kMZISj%!NY#dAxMFV_oIOag2Mv<6v{Y%;x|KvlMoDB;q=bZos^^%XmhgL1Mn*aq zu16NnU#K2+_dR#ZLk~VE!B|csL$^@0OAw)K^C+>4J{Dsak@iYro+`SInCd zg9nu&vv8~me>(CSXd)lqt%`)Oe?Wce12xV?Ag3Z{BDeG9%$_}arUT4I!%dhG5=1po zf(5!jDzBurFvih=E#Ij!21qXD?&WbHSOPzc+PDNtjcD`oMwiUmSSF!C!6Klc-7wIq ztE*Gb)IHCri}9m_22R%KclTfa`j-OPciwrYnvikOrv&(qOOSd%=+FQf#-bYNo1aa3 z<}W3_+yl+yoEluPwP1)j3FV*h)2C8V{*uJT(;{DMj)J^=?2Fh_T8j%y&{l#MV*nh& z7fbK-Xe?86c;b}NiLQiS@BlMzRlNzX((8v?f)j3iAQ-CoN+PU|Ve;w?4GmQ}AtAw= zm6hd%s)+%Bi$FLE(!!|n@`@fCHmn!wQcs&U%?mY&GI$r*j^b@Yrd}|C@K)qpq&O+cw{ztwvZ~d()BO{~f){*C&t9Wr^V}q3LDwQgDf!MHq zz2xQR$s8C;PM-3!ly0Evw=cEqCf!=MlwgFUb=!ia9x4%ZaS9NjjZ=!Y@og$XEA@u) zRW#hh?Q}(H#r&=q(budVA&er*Jw3M!KO9x)^iU_ zV*4Hvl-iQG90aP&nb_l0QcTjfrycSC{<$?kGQtD~?L$Ur0<+*KLCq>s5Upsb?`P%= zA4km2I*7QcrMk38R?YanspxFpaaWCz?vRqT>(GG`1~nrKutR^V=_+kUdn5E?pubCF zH71Rmsr0h{)!IFKe>J8}K5d4=m=k)8_uc=fJpbY|^5lf4RU$8sBV$uVeCO03?6 zM`|4p<02U+k`V(tt%i5(u9LM}ON|vyi~Ho^XGH?=_Qq){YW~ko#OIu#NpB=>n`ht~ zI3(oAs?EIj2O^v>b3&1d%n^~mwheM-pFX|QTDNW!MN4vkBBe4A4EJ)FaH~}SNDKKa zK9`yAWcwKLKC>FM@dp#Z7PAgOHAcIa7gCR$>~Bq8nan7xmDKQ1>CrM%KAQN9Jo@zW zSba!s0&VJn&3+hCcd3wK-m6q4C>`UwSO)!_&2BmByL!bF@VbyWpQA8A$yiY{ zW3rsHWjOD;{q|-pkF^19;r`%>B1KkG3KJX4WrPbp~%KY-0~qi&9fl zy4C=nu#*G^V#&QC^V5(-6Bl=zbo;`cmAe0Jo;NyqnA(tRG zBI_U!yL%HoM?gKr^yZsy>ILDp`93e!|K5A!@w>XRyR2A(#;CHJr9UsfX%=%Y*W`Nsm;h!?>h60Qw>5uaW(q z-`4a5|IVLP1I@?)MbQ3Iza$v6lLMp~7@Z)k`wo&xZ@nn3+IN>Oy$8d-$1Bh{lT8KX z(yMhW?$iv~?a)iV>+ZXq0KArlh6cuSXTRsTf+rn1=`-I$UBNQZct_UctfuH#&OP^B zML&vJVM(L5-XS@8<>JPYh?#!Y;1+7~M=$YGiOuRIjaZg2BCMQ&`o7H=oVvjObKKMb zOj6Wr%L;NK*u@wM=?=iHK?^(S!t$mSAlFu1DTUj&OTo%HO=Uk9QBVe-I$XN<=q2e` z5{rzCP!Y|VF2If(pq4s>3dn-M6&S&LI8akstnq2p1)AUXKldS=Q0etIUR7ZCm6u}eW*$Lp_=8viMXkoBse^ zI3tz^wVO}eUp5T0hH{c6IR~)$aU}@^x zrFqZ~gAY>Z5C(-s;Q}C}24bWGlMc`pFJ3J4W%~8kUkk&uUVr`dir&YL9jnUD>vW)Z z;8Tw75dv&zHJ}f%N+{jJmi-HWo`XGydrJ1q5U>W@jZkGMlG36bsu1foZjhEO({VW@ zd{9MNv04Kcf%Z^H(jYm;qkYYdUS*)Mt zb;LUJ)h{P6O=AqD!Jq{WVqTxL&`YlvOjss2qmM^GA|C-saA)fGQ$LtX=&M$(s+l`? z?yiD@g6+7JnR+M$#QDgqfKmWnK9~7WiRJKd7)Af2AXOG@xqrMRSoBH*a(0K#1C2pp z@y-gj)3PAHS_;Z*rF~+k#D@idMlnG_ee)BVIuickB!+H9-7q3PsegZ&IcKh959lvL zh7FU2^X6bRBNeyc^U>x z?*k7@!HyklOPN1+4x?i#-4?z(wnJA*$!IM`cztrfr@s?I4L4j<((k{bNYJy%2=?T2 zgL!1-^!u4_v~n*5jv~)}=bd+GIsB}849E#vKJuW+e9)tN53;knMvWTP2|g!#zW(~_)RChO zoMPti#u%KT)XO_&F^1ZYlHX3Uw@N-Jt9-~c#4+e|duZ!({k$>;c ztpOWm{bYX*3~-HT^#G7fAQ_aSLd?|_;@-7WR?eT^RLEPgjN8BONz$o(J4s1RmViJ8 zV$u@n!UcUU0t=20Try)wQ*BVzuHhL<6P#dxE-Wk4_=YM8_z&w%GDb+2k(D40CFAvq z%>t-UDvRLoc%E0nf&yg5R74OOKVHU+yHzf|dMv;$zJp*FF30E%f)63>QHo)LRDgP6 zWe9n_WoHRiC+aY`!%G5&bcL)m-`bji+SI(iIY7w@6wFn~dKJ zi5LKa8-}F}uI97`s(urICa6Qb#|L}mv-Nu>*+FSr3;=k$;_)zjl@LcdmFT61f?B7pb zdG}+v`KpWM4j5^^_SU;%#$>1-D;yMFsLZ#4#`FrHIwL)k(MtnW)wm)^zE2wu3Ljv6 zuL`SC5AS02;$l7zd|Fc@!ZXkp>GG7hTh}gf$;B7TL;rXfUL@AYyxFtm$*2EMcCB5( zw@a&z-6b-uwRl3XG663TjkwqCMkrfKviW>G-k*-&8UXuHO{Baw*du@)hso+6Kar_l zeJrEK-6H`IPBnlR<>XgN-wpwwDG0LwdMy^K@yg4uAmHtN(M1=v{p6ERHqd3FPrd1& zAFR>cK~L>H2(WubbX2tA%rnnaoK9!{d+MFCWmi4@p&=f!N2+&imlyB9UFpPPz!(FLRBf{QMe zPMtbSVsau}f>EHLwJVKh2r9@h2}sD`NXE3btp|XuhaPPm+}71WdR7mBOIJ#@ur9B2 z0GvAAAYe#ra2@y_taK@vj89(pjz%R4_#@2yHR94o@)}jj8SmweKuStSUHnDTC2e`I@Fqt zxQ{ZyqMj-U3CPLFEs-;j(*Zovp@SKZiEu=Z9z6tpYn7yy24n=Z4DJDt%X(qf6U)M+ z49Kvh5t%wbAj7o(Rvr8uKcr2{h0)9yc#V=*)hM4XE0R!7)BtuV^`|>UCK^NTpY-z4 zV2u<1C!Tl$I_M#)oUdZ(b?45VDr7ak88!|eS50E6f5-mM`@Me?Vz8#z?^MNdi5dUd zkC}*J*iVA-N#$kvGWF;0W#Vg(sdHA?RCMc*A_yF${-z;P)t+iuvfx)q=+{$8yV)F6 zU1CqRbIaoDd_i8k7;D`h&aysx+8T zd62zWHSos9az2Lm&;tjmYXOGCAA0DaaNOS(s=>l1?VG5 zo%+kQcTbQvpLs~)I=(AI&be4Bz_WR+zJj0^g2!;PI?i!lU4v3HY%zrhaNMM2pxz+p z&j;EN9aN@`*0!}#o!G%T9=Jql4RE&HA;UJM>y zms2gD1c2a3c>Z*J)PT;QNMzinw99G2(1x(QK^Oqab2rNBRf|<&`}XQBW3RnNdiLt6 z^tpoISCL71OQ7oz&fv+Yz_6HHKozz19)y>!lX6&CR@ODbF+Kq<{OkhII>D+L!jem& zcqKqK%7AAm?nu!9xRMEjt43pFo;-vtE+K>U;2fm@9E`p02Kj07*Xq5OUU!ECKnG~W z`f@R}_DG9J#)pS)FIGpZYMt=sTPG#u^-=`MZao0D6=e>^Gs#yyW_Z{mH?FUe1;0)= zz4_cDtd=eSyIca@h)f6i%&U>NWoKs>01Q%^(tOavpCT9tjgSDEU@gu+IWX~Adgie| zGU21L@s%@KPL_e?IUxCF#nCvSgW5Fgr|21Aw*>%gREriZA`psM>C@89S9*H7l4??V zi)Cj@ZQYQn>+isOwdMoQU^A+fA)R+{t7n|^wKw;UM&hRu;_{bCtA0u%wPDx`-Nt-b zSPkXjVDK(THhBeCsF*6?`+5JQOO>%qu1>*tPL-MZyfC~HhN^}uE)}x%*I$2y9^@b} z>0{@)L4zE`1R9Ih;HTD~-KcKr!x|jbvS$8l`Om9QN&fatGIZ3Xa_+^~$kN$Uww8QkV8%{iNw*Kx&6fqy^8=p+nojO19^a!Gn3BiIM{@OH>2sZZ4*D7kZwc*uvbc z^6m>0B(6gbF-FEKA_s?24=0iN(;r_0Y(TAJYwxDzD(#3Ub@fn94m17$(1*oUC$3$E zU>b8piYU|&x##Y?B@7Jpiz{Ei!jq1sG-p7%7&Zq3%|HFqcQRc4zzZIfKd5Dtx0~7P=$5l`nUt07 zmM=c~q7h)1QlG8JRFv0q-nG|Wy90n1Z&XFZW^cm4i?J5HRO7GwI3|7y_w~Pd>}Vyv z3utJj{=7Ks5Y%!VI~6$vIhk9`ig_#&651#%(Hp2s3qYU@#^{150y^0QwFD24*b-ss zWhRL+am)A7xJX&2a3Yn=13{;1{*j4;$Q%SkJzq(X1@SR@x zh=$Gv0G=7qBDFFT#5PZy7$o= z2`E_U+OjhG8fxFn*(AU~AdEFDi?_?PuRoAUAN)&w%J?TbSnbfI*zL;tutFmcwB35z*$k-%gYdUVc)hPX11Af9OeR-?fhfMa5%c z4~~y^H$&NhbEV=Mm+Zm>&t|R`GtOBdc{SmD6(&Gb^}^Ia?BTI;?p3$RylFqkf~ns~ zf2e;oLTJDxL6QyW8!?OF@(wCWW zzqAGcAh5hpQr;-Ls$5bI=>f-E8<`|;1iDtf z8mV1~`*@5J0fFv~0eZ6awY5@SS1Sz&LQz&+1RAP?zHq%1_PzPU*4g~V4 zlhTqx*@1unRH{2z>NV(eEZ5nf8Uf`QqI$e@SG_X705isf43dIC==v&D4My#OQAQOa z1yvO9lx%X#d~twNOm00nWvqGfx>Be@WBUd zaM+)omtT;MrO%-Z#R~tQvVHsZI#_!X2ya8)fK16S!EhdO5&8m)PY%!AlsEtn8Z?Me zrC8f6Jm1GH^KVV;yKaEgE->b~Z|t}mI%Fm%#KYB7q|I(OP!gGuo~FPOm*p|It3iwX z75-8&CSa7?`+hPHmW`Q%Oq2S74ixtGb52}vnfk9T=PiGD@&Kd}e3>z@Q6JHTOiW{e zOWq31V&0scFLm%%hUNv+gj+@Eh-sCr{p!-({R>X70Cceb^wUo(cW4B{{9a}PTj-C< z^5x5gZp(%a9fHuriV*z>r+fY38N{kY0ErJJ=H5lEiM%FK!A`@=AOcj6hHFwH@ zQ_q!{gk-F+7@$t%gqtU&o-SLqY>~FDscyYDapi{Xs<$3{J_jSdjT6KQk44^`u}K~p z*-65%98KMOuo5KRL12R|E>?$l_&7^Ct?FAAPv6J*rtBFBgvg^vG}?+1mRT`TXQ#;7 zS?&E|!B)@Ia-%1%Lm$cPHe?9EZg-rThs-4c&X!mi`{eBGY%j77Z1>>-0K2$cB~C~a zky|3S@#WT#Jf}eaJr1fFX3|zjupM?2X^`UEU^@|rG1#WBG?`)xYt3tRx#YCVZjy|4 zS@P{i|CWE=b1fbPccRzaCLOz&Yjd47&gR`-k9$_mSC*?5+o-{|0#VPIT7UBhThc z-oT|lGbDR;7&Nv(w5)&=md>`WS}I?@{hVa>7^sjr-Q?&@}#*c_lu_0t|MAyEO2z^Txgn|yw!K~KKnJTB9e}%-QW&-d+ zvV{TIOyeUYEB^LCs_Uq!S5o5A-3TsFQ7YxT3nX{bTABRW2TiXXeENCPqyG>L5S=AB zJ{8Opk_jvaw@FGiphKBFE;l^!pyI&D!y}Y&j5j7Wju^n(zkh%BRAYTZgB`k@Enytf zGB-DO7>#5WE?h|czy|0B7Q)gv57!X{GgI`i6`4So0ps+(hFvWY2qWR8%{c*Cf$GTI z{+(nYwi$7rTyb(MiG`#DiHtyh4*zEPnbddSy;MEmdlm5Ews~T|W@gg2 z&CeeX`}{yN25Nq)2S$nnE@rA#VgH-?o8+T{I_VCe&(#AD&?3KvP>sNpiSE#vCw?dU z!%si`qz-3iXRECOhQ7KWNap=ryLMHc0^m1T#*7&wAAb0uQh7MqK6(j5nHoXw7ECBZ zfjUd_*URMZK9b23-;mCIhsp(4-zq5pDh5*k)OfUT-A3rF$0a7Kdy5JS)s{b2Na$KX zTdB07LSg|t4B+#MN}8?!k^@;p2Uz6uqB=>MwN-8!+6Gc_A3$auk-4B)#NtGbN`ltx z{^Ng_wCyXU`hL(2`#n-=ZKF(HxkFxEvWpaB3JWxwoYr7h=8*Gb>+fB^&G=_XS7cxH4!s;6+(1xX`n z?b$3TGyALA4SJ`XAw9|_JB!Mt!eE#71J004NOlW1ZS4f9EA>57$u!L|CKY z5QQP&eX^&nUUIj9o{DqubgBel!f=Sxu2Uyz+o`vNA;MN#%hqC#h?U5gc(DZm3`1p( zyqmga9vGf+Rfem2^;kICUIS?Y^os4qI!Js?k`Q8&xUfK|V+5)dKir^V0vOO265#D& z&ISb9`(4l>wPFU7P!Z8pch;iqxDoFUKKVcJR?H-x@)ki!pVQFpP8xPW5&er_I zqw3_(`eF6c^8)M(FoX3-2!Lo9<6MKf|njzXZdXG=vZ|fv7_u39y055^lKhECU>jlYj_CIB1d)@#)YC2OH&i zNChfsOg&Y~A^n{JXVuj4F@WxBs`enxJ0@coaBJ|b(|-JNzZYwNUUJRdk^%`xVtQ*V z^TtEd0a6YO8cOxS0~rIDCYQ^o24TcRf%u8m%(#Z)LzM`4biF`CA@VZgga^8=+!`3Q z4IMY2va&J*hB6rdpo8eYm4-5l7AYr~mp+YOKk~zkQ-H1ijwnXf!dFJ%Lkm?->Ml zI*`@3c-CJkQDQ{NE&(o$t4tU?4WO%Ea*E}p#ii0WG(f7cdZ1Zcp(=SEU#J_a(eO-9 zWV~Fm&CSh|XPJE8LxSY?HPsRuxK%D1kcsQi zF90@-TwT%c!7=vQzgl9uYMq_cYgVgD3lVtZ<2hSpR;5YOAzifK8V6LT5arQiNons* zA2@34_Sut4UU=`lXG5VcFm~)%j;lndlpdrary;jQZUv7=DKO$pgz8Hu_=LdUumZLO zwKVYb@f7xZf?FoG1l2H@5vko{hu+j~*kXP~9rtwozvP^o_jp&qw+EeNw0HJ*0JqZsSNRvw??K(LAO%5tpa)ysyRJ7xVx zZ|(D5{xM+K2mp?5lG(aF{OzVlP;8PK7gWF#&?xB@ixkLKDXDYIE~wAhpjH`y)w`sq zKuHX@NjMCd*`FEcinbzw@c%wwK!520W7;v}u9NrQd0Xk*^L;(e7$v62G!@jsqsBc} zJ6Wqg{h2jDVI66y5ksvtHW|bnB47XKHTbgZ4dGXm)HHZyTVa(%1MqVELNd~|<$0q< z4ft}>qzHgrj-Bi`dLQC7DzRf8Eb(Ht{wdd8cY`e=A{^>k9?%`MYfzBfl4`X~$mNJl zYnRKypTCe+eFlju1bTjCe7@zjgFV=P?AX@;SdMCK5)D^w z=K!i{_2_@ALl}JMOdL`dFkeE;)UpHi?&pGVnjk9%{VeiYrV2N6Ak;^;9yX!6(6A zs4(Z}=R+c~yeK~}uVC%EwVQG6dSrrN?(aY@LuL~(?~}TB?{0xK1FL&VI{Z|diywsc zUyM1<cgvW5sgfBRri}l%8pB3VY-69N{dNB!2yg)mvT@m_oJ7sv zv`e0ywi(Nz!C1QGG!1&;Xez|3z_+t10opj3Q+sN&&(ESoTEBr54ok8&)n5*#n@a*9 z=!Ke!d<==w#c-!|`Q?|(#EBD?>InPU!S37VW&iCDd=rf}O_*%5A17VShVykpLSjOnXE1?aL_Uw-YT4DTwZ!OH)sB~V4e1ta@rV#yh1qyQw^#1|48Ja3?`~U2n1z?`l_5V-Y zwMipwBW;t^-QAH=+->MKbYqM;D>gRZ2Lr}n8)L|Dm*SMVySt^{NRu?K|Ihb6dDFC5 zfik-PdXx8gpZAfg=bn4+(e$?M8n#Tg-`sTh<=63YVVl-%LeTq-?bNwrcy@LU`tV8k zJI->^`!JG|uCQ~N$g=`GEy}*G0(|`Z3CqjYLAqgH5==Qn$z#%o1#9x>5xU;aM8>%c z9bRxYvNrFn;Z<;3Fbn{8B6y=I=k)-KYLQ5ob?VY%u=N~shQ0gTWA@75@3qdo`q{9t z<1s9&vo*N=`sm}2Ei1v#7OmLqt3uOvddoN%At7uS0Y3_bwkCPRcWoo`b40jsV_*m- z6`|;XgDb-tEHXaD;m{TsBn1yU(Q1Lu8VKR?0|i!^zt?7b^tSu>3L6LkEESB5>@L=_ zO@_t9x1{f+M&m+RA@&Z2rS5OL${TEZS*b@GbmEUSw(pflQl8ixpF*WbQM9RL1adO)jd9k{y|)tIhh zPq7v6y&#_*k#xt&X5XrB!4oI9^pxaF(RezWi_2-^A3^336TF&; zN+%CtcSHgX;IM&X^NXu&5A5X75d7W2&6|l*u~KBKwr~zbajN7ga z5RAnj&QJ(jadNe@CR-3GizB7f5P)Lqwq>??-C`8WU$eE#mg=rcsa*$Hd{S!*lp}wl z;?&Ffodr;fqZXKIHbvTn>%&hHHyV?6clzy~<*aG>fzZ{RVAhCGeCzt}-(%ahZm}_= zM%f*A-9^2m3x@gzi}pSwYC8+yY!MbU1|Mas7EW=*ZVXMl=!Z93QoC+WSFIk7xBQdB z%e8v#3{*#z$buHc!ncD-wF4E7m@t1FUI$wX^v7bDU{M$ag~Lfuzd1v=#=19s(I&N1 zjT1*k1igOx5GfX>&NxN}GC0#$4>X{or*D7!7Y9^VRi~6!l&7F$*-v3^SFT)XJGSpI z0v_Z|n>KAb&u!!*LfFR@&gDEGVz-8GOK6?->nK0#n%Jo?em4l93ui70PRwc1a5-}; zZT_w`cH^*g8`(LCjQ=)exta$!^WF`Y$6^}Drp(S4sDkzQ-FL?yOE<`fcMC# zNaiK;V&!V9szyJOIjtn|xsvqf14856yB-{998sTOlPXma$62hcv{um(cHjJc=;N2$ z8N)kTVyK8-N_23fH&nXd!T|)ZLO#HaZ@hHX0~M|{!JXban3~{C1Lr;LZu;`@p7iq9 zxrYV4tKM(#T)0sn>sq2iBdlu<`;r#D1Gr2qC@!{Tp_{A*0=DgFyBN` z*lR{oG$5C$kCHp`#KCqqp6j0P&BiCIfQMpi732*^2E)6srKo@_CXYEmgnL)tSNmbn zuHqTD8X05K2{I;&#lP*D7hY;RR?o9JGp5-|XJ2BYPd>*+VLVn}UTTR^L6#O9Xw^u` zs<;*i!T8E6uiCwTy4!kJVfz8mDVq#=e-N&gYbnhpHB`_BE5voS=8*pMLqQ=lZkm~u zz_CBL)DJa=i1-AHO3Sj;?)_P~%B%({UD4j%HU|P&AEj_qY0kLn7V8KB+y=ei2!$Ia zk2)lf@;gD3AZ&wd*`7LEiv&6?mOuq9!!0oy1`GEZsITS^`p!0b^eCr#^x})pBeA(2 z#q1^49Rj>Q73~tOSFBIMhZ-uUU#z;jTIk?LsOi`7lcV1QZoQ$K!B)&OHsUQ(Tp=I5 z@q%Ub?vLal(MoYYx~Jd(1TQp(m+JcW@2?qhBA-bkMvU;O5H;TRzC0@DkV}-{P0+-w ztn49eGct5ne*Q^>U?s$48DY63I>_C+!9IQaMN987jEEDS8eOh_Z^ zT?dFj1;K}|Uw9zgF{ZwvPziZA)KpptoZPiI{9Zyh;hB@)YieP}fUy>x)XE6&0~Z%V zMmTH|6r%+|IUo#(TP=7Fj1C?gfz^}=C%Q%T;R?v$j+(K^$Q!8asQkdJesGzs0FM%l z1pH$x`t7r%3g@MHoA=vZLLU2Jzz_p++q`^^-FD-p?xr7Y`sA&bt;5!>mWAjnIw2KB z_(+f;QVA+5(XNabJWm#IsHCz%UG~HIDA-epej3vcLRju|Vlbc((Hn&&aU`yE!Xbhq zLdErF^FZ76?c;HMc9OA5I21~&+&IuLjSDYc5gG!+0~^A_!|U;Vt=_XyBS*PGDk&;S ztf(kY++S4KYy0+{_!KU(1@mU3!cnyU?DUlG zX|y!HZg9P$#=UVN*ZW61sa&sYU-?2@EbqWckb~Voo4k6jJ@Cm!3qmZb`nyGsG1g+K zw*#014UB061j3$uyDgckkr5Dtx=a0)wgNA2z4ewo^w2}jSWVY`M6r9|u!HXTp1J<| z>y6+CcH3>YxxgF0_{A@pR3Fs0Uqm?jvQ%#hM)W6%ic~b_&Yo*G-FS`7U9`+jL5F?R z8JAizZkTGAD|M9>4q3Z?X`F8&Ftm8oL9pURgOJ-H*1kg@D>+c&jgK~v-0R-6mn*iR zqSylCaOcD?L8?4m)B&Ht^pyw!ZGJ`42#(TlXZ5$WrMBt7D!Xz-d&^Ehl25t5aK|n~ z&0UR@-g93%;R;`_hk+s8ciFlZdxb7E3Jb^6 zOYOGB_Q{_vcSX#ZGcACy*xn@Yilo&D!0H{Rw$ad&)=<1x1C6~_OZ`@*)kh@vfcFFs z=n8%A5s@{Lrr{AsUT{R@<|BD4s>J0NHZ^)ws%2tIISwmX62^x-c^jJqfAD6Y7!TOt zloc1)`h_!X4PJTn?#Ojz{NHbGu%B^%;7R8YcqANV2Zp`)@afY#tr35qkCByaJ9D?% zb4V`wo)&AhEn3m<>QMrm(Ar@7No}g)6WBN)jV+-J-`GWu=tJQwMFYL|+UslpAU^ejKruoVCvMV-Y(xm1x@w(>{`sc;jUnC@a30Z79SlG!$uUp3vl}6 zifmg!DMS(zhaJ=M8K1a}654iXbYCN0$stQ;Q$fd1zPlcfi!nbxcDW$U8h>2FAm|Ct z+l*1#3$D3yz3eiJMNdzD5^LdP$tXo3eJeo#Yj^FpH9OeIFupPh3z4WFK=Xsh zl>tE&;i7k~-(bt;PPNzmaUZ)bFJ%oGi;hha#AQ5)CX%sN6f+FPL@@Djh_?~XxrL?| zJUspY06+jqL_t&$fqzv`=-D9ZDOi=u5-kPQ4d@hu&?8Fm*f8DmwK#v_0!QrDB9^5% zo4z*RHt#8OZpVUw(XHqY|MIE{e(BODx9i#r`0tRu1vgD4JR zQ4E1-jzYmM1ZVx4m?DIgpZoyJrJs*O>}>`#$%T&9QRwTbFg_4a^hQHNXiRiNSZs7d zbj#$1Htjn#RAF}C0FFR$zj^Suz~ZvnxFKiX7(S56hND<<133u+LHAS{+#}XUWIn~-HN8;Zw!dgTU0gX+NcpF}#4%ABZ zP$VQRa3WM3I#NyDpGbSRZ0SjN-&-2osB`bTOCD#Cex!K8wtmaVvJ8>_r1_id{yDoW zIy?%32e=nZ9tMN5&PGlQf3DWntyp4L{NPecY$;=T*YB?4GiJLb6>RZN0xUX~XE1$#b;|geYaK1x<70EAlZqK!+o_@-Hck4v=#BcBa zmv!tl2m_)R=UZBfvJak`Wzlph^3fYjHf`vO7H(UMt|vkPHfu_9J*QM%oM%C)0dCV7 ztc@zy9PGQhhaNQ7TVhZ(Wmh#`-&fex16$e9PAL{6%1ep+!X<8;MBtGbz7%ZITk3S>+b&C7rHGJF5dAGo~dqwdld zf8{h*`wG`a9kh^=Wn*eO@m*;4?X^z5;v!B0$JOZIRx&naaGXmjAU><=t+)#JUCiG~ z$3-A->Lpc_AaIUy@MEl?`5f0(FfA1{;ctKHE!&2z+cw+EMYC--kx;j+S?tP>@6^+} z;=N$sruFu~FMeddMqQ!z$Wxs4-P(QS7%JD;@ODuqz5f_=x9_|E0sHXXcWl91&sfhh zt}s8iZw=Hb6g*wdu0Ubw!>NO~zF(Q>(?cF(EVXX%I_n7cLh$5(Wqxo%vUR{dsDWTe z)fgYogV{1~`o}K&lh3=t28VsIn1Jf zOS#Ld0f%dE(Th#qOV9t?UMEcWC6`=kyS8nz-X~vRkr>oT>R0BF9UBSN&GoW_!mn)F z@dv(n5BPdmE5AZU$+v$v1E)wU+O@^5KXZV! z?moy`^cse-8jCszLRD;95SxlQe)3)RK&AS=ad(S6()_oswk6X)aMA5PojJ<}4j$x+ z7hxy_><_Ukyqud?VvD!zw?YgMrMoM{E@TrVL#4>uvw?neKiB*^jyC#}L0mv0Cnk%bu1Hub9XI&(&<~9P#e~wL_A0 zH;Dr$-g>JI0*e(Zv3|P+UKiX=xMTE*^F_=nBD`cICXtE8LRR3)&xJ}>mi*R)=hTgn z@{-P`h)p4BEx>gk0ErSs5Q})lAgewkC`4+L4f2?ApkPnnvk%|qHwAY*<9_m>1$P;N zu_0W4Mo0O=cXA@dAnCy2X=7gn4)*!WK*X4X>PClzV9RWYyR!I5i-jltv z7Or+`tE-zvjm9+ATNH^aN6TxC-l{UK4U(#HG)_U~z%?S(BB)-DFFC->^= zL#V&g_;Ano4&*@R2U$#6p1pq47`y9^KiF?>{S9LXJOkSp99m{(rk!}=iT2b}PdUQ% zNC;J5{vvvPY7s>Da)xiuKKra)bkRkw?yCRi5xpuyNl09Nf!}-gJv-yfGu*Wce)v-x zKK^{%JY_iUUJY|!@S{zK2p`uU?#Y7(jfduyW~ah!zw(cJoet*)BFFh8B-`L*XJlqt zuXC=qq%l`wYY$;uhiVXGDE&+kGaghP%vWbBR}v-m%QhE|=>^F_c3zJZ>z2{N;=&1L z(DbLQR9roH2<_25;5h?;>KDk8~)r}7E#B1Rw&hK zMDk)flrul8@atHq5A)pJ0|ca-t6tYe#*J}fKR7l3d3f{B8+p&qxeSOw1k|Uzq}cZE z%(V?m=h(EjUbGEsm%GY@rKDRHcsw{E#VSH!RL~EhMZ0bL?2qC2ZnfJVd(m=+LiD1_ zBOmS2NQDMwC0c9{W5Jvt8lCeo-2x&cL&R|uVr8VhRnk1>FN}ISpQ@iXKwsyY7&-L6 z+r+s}@UToE>NHkDfTSH8ZPNk|hj-}F%O*hlcIq|QB9qb}R+;V08^Mn7ujYvApOX}7 zZNY6};0o#MO2^lWu;^zpD8Bu++w9-W&u)W8T3}`utAgNm{-&w7q({n67+N16miszQ zI{xfe_ka%@FymYw>vt#EYHdD*=L6wh@6f+qP~F z%E)YY3#I%YjD;Xvg&u8)yD zNa9mLlH83+XD|{yRNJ<~7JmAHJ^Ks* z1L8M62}@x(V8FJxFBGYj%Y$#N&-xR~iEs6WlGY^m?d~>mJM;+mrIw*2az-B>0jaw) zhunP&x^6X3>Sqx~QnwI6sXu+oud?#hx~$AZD22gItlFPvk3KNb7EXTC#@_U23-34* z?vS3vIIpq3sKa(XZOthU3^B1EuyY!Y#E0T;TW!ON=Bc zQbaha9DxoI9VCQZB~+0{I^odYzJ75Js4p7($@~4)M_(KDq|Oz_S_`oI&0z<`&Ggl~ z?TICO(K`&V7Kld=05?IvehAFBYGCDHjofPvrG^0aVLO-G8@F9*@4o%6ojl=W-Y3c! z{fIXW8!%viz5Vvv&d5^)>{oGjy_^poH6|il<-_-e8*Xq`;)H9rGtVR8==BlF z%0Ygf@4NT^>|aklVcl^fb>5XXTY48%52$lBK2xQR;oyRni3rjn{CNwpx>~rIRUXMg z5CqVZ_V~TOC8FXo>x!Ewh8tbnQoG>Xv+bSt7uuCF(gtj80p%7lcZT9eR%a}1sqRe z02AP*#tJZ65~ru=K!xqxUunBb%558j?It2Vu7>i8qupt6>tZN743W2@cgdhv(kL-Y zr3EU}RN+yh^?Ry3AQcwR%5)(qd1t4Cp*|E+(eB^iNn&#R4&%bXO7~~dU;L9WK zqxsoH@cMvF&E?$9TFOyhJHl6e#w|@p>Az|!Q=~f7AyE;`8ZwQj{`H)02?dE@*6#rI zCv!k$)}e+_#=PIVbscNK0&wLd^#45~H#jxJazx}}oMmvR8(?tMu&I-+hq$6K5|NY^ z+lJXwtYrH-yZh<)EC*MRwfILbZ3xCAhuO&NIJn?c4Oo76(z|xbgj1{&9v}j-o^QaC z-jBXk02Hc4%f4Mwn>9wl+1jY-4|wlACUDa!c;uFxO+ z{C4X%cr<>2vuG!{5H${=UB7z9ne&85KkL>y2A5{x9vm>I)$x+NN&o#()Z}it=_bp_ z>S*y@hhosy5~dE!5(gRDY-xrG8Z{dF98X8H2LwM#4({n|z<^EH)5d4i+7<<5otBW`F8(L&$c!DimcmdmlBqiNe8gQCuGvf@B<=+ zCPfg{dCB@5Q(-Ng{Q`w@@9 z2}R_t5Rc9U8Gu!^FV|Mgn`(di)305{L)a;2_Zng$2`#ObaDP?e41*g2S#YWuU~ySI zT`d+N{=9`&1geJ+#HG=$SjhukclxCV0h@G?gN586#;SnVC{SJqb(=fs1^eYKzqCKz zeHS};79)_<`rIO$v$4>r4)|jcoVR1W-S)#XtayLE^*H4MYe>m-k$e;r&MDlux-p5U zo717wH!Dyu!BeV>_TfrxqZO{6-&Dt;gw^cPdocbYJ6l|Gss$syl{$#Tco>*zI`S;- zRX$E#kDtwF6}P>%AH1lAO>b$%(xT;3<85-`r|;syQ}w8>x+5nP$8Yt!uYY}c^37%h zV;MWZ#^tXQud@|P=Go{Q@3)99!=U@oJ*4i=_{iz9O8-uIXn|pD$romqOIiq#s1l?B z({tcxFVubvaMTJedRj!FrD52TfjgiSqTaN`tz9B6n?xi=upthU3J3XWA^*a}SO|WV zyyNFTsT|b5uF=gN5hjzG)%N@no4Fz1-dR^@%gf9P-owdUgvICAL&b-I zEcefS*=9cRC)>Dwt+mU_ahpVO;$`G1i|(B}cbY8hMQpjcG^@vvocf5^ef#z~V>YB{ z_6A~9d42HZ=_7oVzc|aUz5a$>dBx=}`jgqHc^x4)5Cc!Z7hQihY9v05L&4)d?9RQNMziw=tvXLI7$3@^iD$t@G zi~uL7{3yDY^K(sqJCQc?v4*)tfEUO8tZ<@z!rfLdPSRTy=eC^4j&PInA*}b){1WD# z_HzjkfYFS71V9`@J;WWOISXn^>k0yN!|s*AFf~3Q;-g@5b&@9S)vzk$XA_F1@3E zH$K6aYUO)FFsfgwm);Rv%4MRi%E0hIVV-T@y4lt*o^5aZDn9dd@4jP zo^c==oF@h5v7}cZKIP_cp$KrX*sDe z`1Pfynb+zQc`VT=y#CtjcJ|q4SseQAX`|0Hzoc}>ZLb5DXmg{{(3t4#csja0Ao@XT zB=Tt2yPB6;=Om#lSUkoE2l3rO$40*hFHd|6(2Rb++!j;EvD1E45+Sx8E#kRF$gskpYd9Lt;Wj_umF*WP&j zbvylxGu#N*NSw;EJOW|RV2g0gv>^}A1VQ2WPh`;~H@SH!%inH`QGxh793Q37mT&|5 z4zi#YsaAno5G}~~%5jh*;z%MQ>DY>+izLg9wE}XAU~)TYmkU3D+D3+^d&XTpf`iC7 zX}}55OCK}jK)x+}>2KBoPV4GTTXB+(-Wbnp&#$oQNFC%V$&av>Mw7eXmL~0Bv+$9 zZ}vFNUiTCaDXXTuy?1GXOUgs1Y;`RH;xj*YgWYi6Fn4e8RkvDvc0a3+ZSC}WS;<_z z#3@yd+F)q*YJ|0s5ywvBCsArJnR+hh<(3J(ZeXjNPYJ{p8Zj0Mki`LKt>F5$4kscK z?jI6kqAWR1o-O1r7Vj1qjzkinL=Nsl!6{m_`C<&dI%%ychX5)^)>~XzXZuSkZOfh_ zo5$vDZhkd-jfAMe$Vj1(aqC1oJf!KHG3qX<$nZs*bmTsHim-{TF0r?7{gItLDjRX; zb1p=xh)xl?@|F7A-~QI_yz@?1Ngq-A)iwU?6F#DssC>?sub%kegAeS46Hah$&Lm;c z;7y-7(|!Y?J!|?j8$N2BopSllShPF4&4*tDu6QDYEEP_BYD%=N+g@y&c4B14Sc?;; zIp{%vzMCi74DkPjND*e_{#hwR(Q_xKi9OmJEV5J1gQzCnj3)p%>zyQh2J*V=+ z_~=<4r7ei~0cN#F+*jQR<3}jeh9opW5HO*9s|*n!dS7!)eV{SY^ZHhP-i*_Ij}ar7 zRt?0U5k3-R?Oie57QXUV*U+SlPIkdn*IEzoKm;zfD(Fnd z(N%*#lc zTRwN1efY}L-n$&*GCNvI`y2};jBtHeEH3$oq(<8ufvb|pPX@B;W6eA-{IhyVeTI}) zomsfYmcH>XBwGpgf3JLGNoko*JwQ0FS8BL*ggdI9EJk8+#buYH|N6T1IqhOAZJ7xG z)Hz%sB2`IWD$2uo-e~ChS0(k1))ukb#MxCo`YmRN4}@VE3u0|j)z*C&%d zwXsA@RO)fkx#pMB&MJT*A4A5qO$U;`yb*OPm%DcS@XdO_gM8rtAHfS`3T{!M^xK0T z`lNr`1vlMc6VAOFZw=+vB`v}RWF@&kQ@CraUodZhf4>3!WV|EyWImeKRYu!HU(%R) zE4JB)Zr!@-I*c$T2P3&}KcQa{57ZH*YwhBh?wv4{$)&%kA=Y4Pq4b8{-9COe$~~Zo z?k(9ug+y3lhwF!Xt{t=9#ZA#(`vm`qqsNSK1gb2Mon9yite~{UW~|M#JVG^wVw3@D zhmZt#a9Xu?!3=x(v3qR&>ZKMM9%DJ^E(IsG!7wA*%0a#jATTW^;vi{^1tiYd5hpqq zA>>Ow;?}$5J)md4ZW1x47CLun5TDh#Yh4zvPWr$RyFyweSWz$9m1>)`&P$=;brg0cbMH9Ft5*evDtcn)q!d){a>MgZH zToOp$lY63iQmmS+l5G5I+yW`eLSixTBoJIsSS>+(7{orKY%7Ki>vR5 zUVf+yA<oN-|axTzp#}x>9Qp(VLl>*%XaU zy1}@cGeu@AC@8e2pM1)0zU5|D?v+2g%X*DGm4F2C^pT-^7-}gk;&G8D4=SEwz$Tv5 zy!4XSF7;jW2WG`%*n>p-w6BUmFMjAJ|lo>IC{XdjEG!R zIu`uHlk#)hVV#ilr8=<3R;P2&H9t!L_q1gEolYiw?{4cRCpvGQ1XGRKdBe#skC5eA z-@Cx9IJf#7Ouip_+snbhI2kHWSCIQ=-1&Ac+jvERIU*n`g%fM`Y_T27rrMI%|K_qC za?;s0_{1};W0!6g4IwGGlb*0ssd2@5+FnD(eA z-FQN91wedW#>1yX1&l%rzUt`a(EoiK|S5UENAT`iFx`?zC0ZG{Q)`Bkpf&b^%J6kXV{uJ&|DqE?nUgK^ zEwu(;5_a(5*}I}!>P3H~IohmOAdLuVkw*REEg3_%-RqXwQ}_SQ-g^G8_TyXbv`+m; zS|A>!P*7&m?N7wedYiefzChhVjjwNGzbTi?o!Ohh*aaQ(h+h|kY{x^ugL+TyJoo%56 zhwvxjn0B$wI-JQbqS*(4-)-x>+&zTBE*nC}>87E|uw>3uyX&q$*oaXhK{n$3_}Su( z`M4j$kPUIDw(L{hl=p>yS@y6~ETkQd_eD5qr$+scDDjxL^k|*nJqV|IaRKnl7|J3N zN7SFb9s63<0fk9MXKd*LTek34mvy_GF4lMGNtW5Aho!X1Byw9Ku5uz>-@!&;qKcr@ zc2ISJP!^82G9b^b+E@7 z??&=KGIGqt3Ro z&biDwb?asEE#yca?m0w;yk|JFR0JP+$S_BH5+B@tRoyg}z9re=0$vaoTS;vbF)m-c z=bV3$ee&tmR)q_~;LJn}s6?bPA2cZ6FzHo~IMvyq8GUZA^2ni29s29*R6|<>P3c+! z@YKV-ldD60oN5EGq+l8TxMHi=zQ(rB`_MK`f5T;e*400=fg{FQE4&Z|MG~lm6}KEh zw;t)3Ux)I*cdzu$L!X2WM@gzHlZqE}`zmOoffbP|jP0`hDtvG|U0POmw;L$$^ngHh8p*Cm z(S~Y{k9axKdVG`T)LxCVa9BfNgazT+ESW$XEwj7W`j6kUKmP10>pyb5jlbeLqRI7U z+@-CJ*BvT3Yg3VRPOi2tsnJM8+1!J3WT(;#zuTKOZnBZ1$Kdto-`4+(i*ec42Hj^b zsck-dtu`JxBs6Al{ObsN04#?Z3Ze5XXT*40JM~@XQKN15!B&j!c_BLdsqx{;%P$rj zcEfcy4Ef7n|6&lk%mxR7ZfFiCcx9Z?<=k`5Z56BNP|QQEej;`cAWy*Nz&5X0>cTB% zXLdl36M+e-6)ZJ!HCfVi+0)C*Pk?07Tv;$Hw_T7RzCnkoFuNVLcev< zrV_+AGS+}lfooNSBk`G2-?x9<`%72hjzh;=Xq&cHhwG+lN9ckyxg#-}bMxe$`p+E% zNor#~`h+1^4ln%hRqN5UD?Ssiag`9kum<&-jr%Hz`%XX5uKAPSvF9GT)7teLVWI81 z1DA*?(Nz>z`kN#N&Ge(xHiBe5jcC8p4=y5`0qrOgkZdHi>xi`D0G7}Nwr%Zdd-0$5 zH5D~<^vRapbC9*`)WcdN6C#sf7}9MO!KFo0sszsaf))nq=%Gn1dOmdd?dFrn-CBrK zCz&Hp>EVXrrJ~1>6s(vB+1LxNvBgv0u{WN2z}30c;4`elz%dq<)`^v_1)Nd{Wyj^9 z9`u7O)`K9NBI&L#}#XS_a_DDxqTo|{(5U!%EawJ`v6ZLyG*n(I8Vt=^nPRqMAGY7Z&ao2d681_=_iw8|yBupY^_V zZcP-bfH2CI{6hryk(PIOu3!B7=;wH7S&)EkZiQ$AOn*sz34lhAlZ_8izVbJ%w7Jhb zjL}xEwV;E3NDvRHEyN)uLeInLOIHyUOe#LYDb6Rjh*a>UhUSRt&x69QB5?JRHdfla zIeZN)S5=g=na;D_o7dVVbW!Jj^pb7P-P_cd_5(&(RBAe*eF+K@80zr4>@u9X0-Hyz z4{~2e(;UP&^$y_OF-n?p`SKIZb>R+4_hMSNwT?qi#Mk~SZVsG%{jC-e6p56j!j|tS zw|;4Gb9w&6lTWdUxBlL4zw-_ocviBNqB2#-?ndahv8fIhX^J0lUwwHsKXX?bapmnc z=ai!!Kqy4tMp+2Nd-l1hRte{R9t@&+Q{J@;e|)oz#P}&TH3JHnwSvm6+)-ksxMAzj zF2N!L7$-J2HCW-bZP(UjPM=~!P8e(R-gwsfopmW*f7-wxP${%i?V@m@Z_QQ_`Nz}I z?*XYDRiLpQoRsM@U%7C$wd>N4aR|f{OSvUO@In;BCke7{-Fk>ip$E6{(TE5&m| z#!7V3fc`jR4h;*fg^Lh`cQe~vScXaqs^R6uwrti%?u`IMxQdvimyW0ZObl`J|LKU`>9c0pkU@hWq!6JqtPN~JN@2yU*s#Y|?yQ8!WpN9R1OZjqh6Nwniw{k- zb(=O@tLz?@h)cO@A~R`6A0(G$2=$4T=O9BmWgdy*NS6Oh16?UBBmh+)*5L;>dePe+ zf%8RpUN}UEwo9vR@zw*5D2WQF!8h=9d+4`6wpLyHSagS;K2k`74&77Mxo8H7F_-&Hz3l2aUzuS&1DWc)<(;a_FNJpMYP|@n>3Ahc1?y z*4BwcLs_t75Yxb-P{SfDNA{YJ8eflRbmSZvSIB1$n%_djj39X{w+4vpDv0+0xJcqi zr)71rK_{PQYv+Gz?>%sMN$ zUKi4uTx9qYT3KwHXG_h??5wlSa^F7Hk*U*XxZfj2jBwu~QjP|P*JZ{*d5Ie*4)5g2 zlWqF6X?FRQS6eG|hM~hr9;^v88XTL9_5;(dFEqTgK}nlZ?^M6No^m&u9ULS$#nBe}6oS z&`m+rc(W;xNn>OGd(xrfCiB)MyH8CDMwO2ZH6^s>~4@E(Kj$FA~HHyp9`+D;@mCv{NL_(pIiU( zjCJTg8fFHb+1b!+zyh)gTbKUr<1G@23PJ&AJlQ5K-KKps*}C=bW%FN?58})4L5vYA zRIj+ff)O9SYO2WblcU-L!cVopW)M=>=&Wuw<=F>p^l2A3$-~~_3f3wyQ~-DQeOw;ne8DPA$d&5ebJn3ai zABd5K^yZid4eSPwr|-T8+=2^{6k1kn#Y;c3QYN*GTZTgH%1@wTrAz0v0&Cj2xMtdt zUxTGS$Q4fvC408n$FDzauRr}4SJ5sfoln4s)>b7kHe6xt>ZN}q_dE_+I5h4F;5~%( z-M3FA2q(&CDyCx=ym!4*8~6)BGX~Q}&#Ktp786OWoW(Z|9kLBeXWJisdI{bW(yV1S zi1#3nmN=;N#X&Oao7Y|Xs_;9gjaN4zHT*@u0nvg0r=3lLh&hF-^$U%{D@K&HNNifQ+&?uz2|Pr>Cn-6 zI|zcKnxCIM{awKEU?32E%8pyeu2`U%e zXLhpc#K!ijzaYJ64_R=oy7}s-UOY5;z1!>>FDdezlJt^4FP(P!X?8mV@8U^MTc69@ znSXE;8%c2yg(Fmkue{HD`&hU}9r+jZ$qS9#X*HA=SP5QSb}yQ2>pp$SRr1tJeq@7A zIKx^Yu?daD$cwormvpXm^u0FUI@jh=N483Qi=b5UU2{L04vxrm1H=0ew+iN?JZjl= zR`1_y`!G1$zGa=Q!^io1FFx7yo=!3bodjW-YJsRxflwe66+i*;x{89h3UnJqjXiZC zQ{}5|vanPW9B@w~q&XAF-0{slE`4S4)&S<3gDnUMc3+|GyIVVm|0nLf6&s3H)@SVL z;NWswytB^YBjJXkUe^*2Ht)TUOTUxGTm9b67SN`XtCwmb;@g|!s?~RsJmmy$gxm&Q z9plCeDII4)fVtWvL%uNZbFY>uwqp867~fw?q{55s)Qf*?Y3M;q6)?91b*uIHHUN(l zarkuCXvP^|C4Ffv2$nJJo(?2Hs%MYH=xt4HHW7J9p803)vEv9gyAMkCwUV| z!$ZT$4a@OPvdMD#w6ekjR+4CpQ~2+IKU*@M!dOnWSu31Rg@3;=C!TWDhNQ)7M@6jt(k8J8`v93wnsE z1iK&@---*~f6aOi7;NWWa`uRGD{_~pX^@X+oA{&)Fgr=xFx~c_-6PLvNt)X1URbhekkBDU_8eMX zFsm*tg8RGE)~;A+YnLzdUg9`_5Sbmj^|s9HZWhb4QE@HsXdugKbY2C-o#v)L~^=$_9ReW9fjZZo1)7F-*`iBgE%dxOy(RMyXAW?cz(i(O%DRbeDDTTJOE2UtHrkXJn&!ud*EB#>$}I&5~D-I!j4O zw)S3w*`|OW5U15KEwvA== z=!dke*w*hZvYu&ptKr!ZBS+aK7oKnbe*Q)4eI~&G;?sCv#=Ah9xX$08E@XSeN!hC& zzHgm*zv&q+>bf?V>c3j**7f8wtbFq_`xG?=eQv({uhwVGDcEep64ap5`FHQ1onWzw z&IbNa;HD0pI@t&By^9*hc&lAI&-}X&XFZK~(r&4fXzlU5z#MV4k3V>XJ>cdy&jx`f zgJTlhTWfK}m)&CkYpr$_&V3zyp8|Ni${0#LZ;eH>oFb{)iS z+g{zfXS5*vC5iU}0BZaYLPS&&jcLL3PuxpV;ICw09dc-zV(!-Q!%^q~Z$Au~BZLm3 zkTFj%giT1^R$DOpQ@efQL_6=?a~u&MoF_Lbas#t~01RvP)(`>`@z;Upd+hF? zyBc-I5GDkDr5d@>f`#NPr8V)nD}?GTvO*6^LJj(Sw@FK;mU0pH;$qa$4tN@H2)4R{ z@4kJawFDN$^^)Ve)!Pd3A&OY9bgw=8$RFG@op3)ENMtm(%Vwbx|BtM|eBZwQUZ1F# zgL!!`y zYN(I;+1CQ^8QxbXfyCW!9M)IUU;Y@OcIq?4ayoXllg_@#=1zOp-hJ^ITQ~W6%N%%$ zWeq#kf?MZUJsYNQ5xuB8h->2Sk7IYnhrr5k=f!VQi7Ho%Fn>O)V0&sP$fgCq4tJ>d~sUT-k(-DB!y_4OAg-4}#-&v0bym8464c=Exx+@*Ez z-rYWa=q5Y;zDdNEl?b;QQMaUp7!lTc;(kvCa(FIZ@3(5Nrsya_PW2QVd8D*gZxKvd z^mNZzDNuJ2dhT6qbTO6;VV*d+17}$AJ}cX@(x$%pgjwE3SE0*(b&vHLINVyc&cHom zi1Wx%ORxcl57|^JZ#R>4LJi!PdlLfJ-KUnSD05ImE_RfTgWG`D8`T8=U3MTJH<3uy zc5m5$U-MZu^_>@84(<@$#@Y`YXOZ!V=8sxnEkte|8)Plm)ml?E9!>B@`HdAgI7%=# zC`OmPUOHGq-<5-fecqMkcRzdX!)o4UL%4)92n-phC-ojggvvGc=xsl--~Z!fiv&My z$Sbq71YG6GuQD6;>u&goBX}zy@B^Y+qQVjE>?u@Nug;$>^XOdh!H?HB2lMp$M?W*;h?3owoz*gnZ3@h&1* z6z&*z(#fd&Jc`QCwbqlsL_zI)gHPF#IOfE6-A=C^|BFW%U}|*5SPH@CespGMTk!Fl zHkwGP!AMCJd`9Yl#7OlI!%gYfu_xp}@Fp?ldwEeyG}^vi(hspWI`!?}KPVzHO6LJW zru&M@$UN8zx9_xtvvBs?YoOK0^$3%|^WW)~dM}sb$D`5%9%AqoD1SuB*fv>kQLZg` z_hmZ)w_`v1=}#dt5Osmn1K|9M+qPm$9y+_F78Mg`g&>*Zb#-`qyD>#BVtW zYQX5jpZODr5m{ntdrRsu)auGhtOE6i{GGY>=Cglm>i&MiMp_n1`4Y7yw#p#t8{v`B zU-Flsi{#!?DPpH1NsIc@sRPiDw4UTiV2)_X(;`6q>fvBi=*`eL%j`MA+H~q?qfWoV zRxO%o|GMvYwq?#FYtdzpbsBlPMI*8dh;8K-#F{!R-L)pdHFotNFSS?aN}dZQclsYW zI2TXNN}?*%fj;6RF>%$JX*TnvzuK>V^(#B;jMLn8-ILp}-Me?&9e3P;)A_TTeC0ML zN}FZ-y`8E(O6pyo(VExO?($b2Tt75s@_B8OzG^-0tXjmz*k2!i!iMzgV>_q5WJxFe z2(_Vb3$3eUz6E2*8O#PpN+Q(bTh28R6WWAnQ=(0)+N157+oUw*FQP^>%A48ssCYqb zBFU;ny$J3sxT6XmtcCk_*xq%EEqAI@(X;No``bys{I%uu=wsoDtzEv-X_xO|m3g=^ zqAQ^ZcBzR7QI)Av2teW9AS}ZI#cf5+;J^WN_w#na#ocIIk%G?0v%%&qTY1AvZQwvf zBE1Qe-|jF}0U>aekBmd*;>vAe=|`$U>vZsqurG(teycwJsU#SY*Pc3XR+m#Q!Vl_m z_S)n3+W9x$X$=H1S-q>&hGfOjO*IDnV88zLukDY2{G;`5-Og%TwijXnzcX^uKX#+{ zpQ`y6mm^5317Vh0`hT>+>PUhqt*l3ZHTuZ;!RtUP(lXpm^;;>FC&&s7??b6F5+&&I1GpS>IB1kpJH!=>?xZ zN$J69DPqV$lWZ-9p5utbkoqz!3XBGh<)%(@qHmW39a3*ndjy4AT|`Q2(J>Km{a392`9HL($P}l-Asl)<9sM2<+_?G5x+$r52vQQIT-5N| zLhur9z)H%h@$s$^2&nJTv!_nF@R`cT%`|a%bs|io)Hxy1%S8D9Ksf{m?#P0PUb240 zeD^>|q;_%=8%bn(d}v*#9OZ)>84WFi5L{Pkb-BxJ&(5v(#+z?i`>gg(w^Iv11BA|& zy(PAMeV&CwG%cGq#qR#ed9F5H2>D!>kcm|W8Z6oC~=yS##WO~I%T4TwG0Q)j(|XngW#+wC`1ou{8okj z?*S{p_wQVM|IVHHiC%Z9CqY6w_ZnoG?XxW@wT(rfiyIgo>mq5vHUdt>#Q>R8hEE*i zU`vy`d7^xeG}iS-?O?6Uz)Cd+JX-j};VusvF~NHF8g3gmuC@iUKCt(nM+f$W`z@pI zI7`JZcQ|33gX2=oFQNsZ&(ULq<0JE*YIZfw=c%tuuM)mr-|4q7l=M_XrH6-D`>nfv zmk5SF`sgEfU!weDKQXp~d)57GRo0QTU-*XRkvNdjAr+=L z6K?ly_uOyup1;oq<6f`DpfdE=9L#9@>ai0X}> z!s)WvFRPT4g*A(INmW80Ra=`+FVSYGPcaaro*+GMZ2%R*xtzc=`}6Z`|L$$Jb=@jk zHj@A}iw+XFp((Ab{qPAEoau_Uwaq(bpN)7Xobqusm{f&GSX%;w`anL48#@iKAiAiZ|ea^YYR!@D)ZvXLFcH?dL z5^&;T+p@pLqFIM}psyUrnyTkxvw`Ez0#}4u5ghq6e3#Sv4Y8gl8WFro4)jFuDuFlQ2l@Hs zq^G5MS9n9=JL}N-EG^k*(_VVg0&ry|U7jFB6qO(*P2l6>>UGz*IeKWoBRMoGLJT4l z6#XY;=XP5(d#e2uHHHbNjOUKX4-htD?HxqFo3*x(U=fIwX1`~5|NL@`OwYFV{l}Oe zVit**i5NrAX=3FAKk`jsPR*Ng61~^RR`MYh&s^zw1_LQd9 z^&pB+PB&B_+Ge4nm`SjVB)H;Hzz5t6mD|V#7MEE`bz<#p>T8h!uGgrKQ~*>r*RTAp zLVZRdVFMx~EgPrz?Fh0lX8eU1;LW%BQ{J%IPu#97UCJ1KmZjn%E&?&Ge{>37C~_?Af!&?z`_kyXmHztPK{~B32F;cPsy6C8?dN zD5le5P1TpYav}=Tc&M>3`FSP5rJ{yzEss zUqRl?)Hcd@)!l*MXkZNd;3$Iz+=Av0k?BVui29N|tA>NScgJR1vt*vxwk68irGZ0+ z+o`{}lQ6nn@pawWV&h^hT%HXuuo9tOOPv*3-B5K<9mJs(bZO41&s1BFz=Z%7am#(x zrw*J_K`8TmNLcc6H$mX8u;p{6+N$LT%MMIxW!WPzZc_9yVA~H4W&=`BsZ~`_W&`ux zA8x3^COb(B8EZbvz|a}IQa^Q>l5m0g!}YVfa_k*cRjoP)7$8aEq?a3()6-h)-C_6q z{3?taC%gH+dw-c_cvkXu>S?E0w+9~}Si`H<>jyU>sl>0k#)N)oZ2I@sP{E)!BqE&D zvPzJJ>`20aVM)iTqFY*fJW=dlf)AQW002M$Nkl-hgBz-Vr0VS6+JA&N=T~>(?d|IeHh?Zir|`*5P?d_`ch#R{sBxWDu?t3{J09 z{}ML4&EOF>eaicG*0uRCT+&`U_3;+Rh;TE%zI2e46}w010_wfF+8XQA+y$h2{x)(gkeH|qg)q4QF}Feti}IDn8m zEWn7-ur6MOKC9ACfASNqu`fl>Qt{5qtLkhHu2UKit*l!(-4VOVtx_zB00QNaNfuH= za7kvGI5kS%q;oUe{XP~BG#3sw1c@q&1Nb!yXV@=pzQsCZcW}z*fn49b>wt@w{RxrO zR<2rRUB_QwwYb8O@r(;n0HQhwhh8haCG}Wnp;w3IioQHRv$e8dq9N015se?YW?BnM`HljOCC1}^<8_Q2<}s^Err9ck1u88Q?y&Z!PYvf ztEI9LiXj4=h=L%wI|3;yP>ICWA_N@a1VZuZhk=UF&VQ6z*5SC!BF7+}~p|0V7V*#^yymZe>iI1=$E4yQPVesXnIS!OjDa+VkDwW_^aEI)U>ZJPQz zZwW5EG+@{$%R2p5Yu_0{E47V_W*8O`2}p_$OKpKm*)%j%D&81lM%j-0>~u$|3t4&A z^OTEjga}-m`i?oylBMyJh^Qts>d;t#dxyR@>F5uJ7H!%f8v^!Sas5GmV7SCb=`z`X4|T`sBW2 ztYGIq?MXuS-u$O0ZF6L@CC9=gMcpwGN%5~H-fkD3izl6;y%v;^rpf9y*vCTiMBsXf z(Q2Fv(!Ui_kWEjcF5}nr0 zKleO)@#UAS-#MvPM?^X}6Br{RRYh+(NE~7EK1MOgu`nD*R0p>dXtT;X;Wm%Zpa}^r zZ98x8!2M?z=+goiWR<8uMurCX1rmidJG*0h2wrx=j)ZL@c==tPaosi7#^9kr!|$gs zqa_vEs|4Gw+|69VU?@5UGT8$ZAGo+1#}D7Q2ZRPS5k%Z*Nq0m5!xAQauRWUx4O?xm zzVa&iof*y(fui%s!g}#mERaz*$;aK!oj07%%1(Uq0Vku26pJ*Q$;LvUG4hR*a#s=x zK30-yBzJ3m;u_>5`XZfi)|p^d2tEj*;)+_^wZGOjt(tGIJn;~m#UU1kpW6}^H>Xd> z^S<`EmygkdukR17-sg{mkF3+P9!^#Z8^=y7C;g%kbOvw=L=YAN!4YE#^h*L<)dsj@ zRV5hj6zsP3OBdSuRZEqXOC36PA(s4bd;#~h#FTW1hL(79i$RS-;%l;I&P!CM9kQ2L z=3LPnsEpuLZg+I49%87bTErHd5*CA`C}P*Q?PMJXjj_`%yB25qTWu2r*vW+17d3iA1VHuM!=sAY$G(V8kbt8<{JKW2lH?G=#DcgJM`B0!BuSUbVa)a&=I( zxaa6)vgVB1C@NeKk@|uyN(9rc)wcfaM{M(|h4$>T&)HavKARJ=j?1UaNDCG$aNk*3 zS?>GTK6t$$TI=g3Uq61?dwRw#FnlWjgHmRvoG26Y(dyXU8 z;5Oo<(<}=(P0s9St5NC~P?Re;iTFzBEYqQZGEQRN-s4UwVE zqwq;1Yo~$vQ-+Jc;{Ao_{%*Go%NC*vHqBNooW)Cx33zDVZzw*pQBjCaz#Sju!fXhF zc$Pn0h3Juvy0%uD6H-xd6Ga4*ch(52sz}r9b?4p{cluv*P@VOWIN9McsCjKLg25l1 zN1bXbKYiO4Onuv;&b-VDORFt4((8v|Lx#FGu3xbP1LGvTd&r0L_n#U^t8t7DVq9(f zg_X61s>aB|FD%|-I`*+N#{BPh|BApt8P;LI3APS>-uUb|qy`vJ0fQl-A$If4H#vg0 zB6qcgn4k^pCxu3pkKf2~R8-I#tgeEj1uM8Xa zmfD7V^wRchwc9TBLX!48`An-O#&;e1ZXqbvd#Vc}2ae%c1}xREFou;C*wU#V+Bs*Q zYu$QwbNwK4eMe!9ZQ8uWp1t=su6HAeu2QL8GZdND7@;R`IXQ;g=xTlx4{mYwS}l%| z7I1Nzs(~XvIH&%hcyWlr8GLfO^&)VD3xI)(I{5-!yLOGOed@1GmFY2Xn04$u*jlBd z0wJ+*3y%N}!Y`>KYuSiE|3Xlzv)NgrH>Hh+7mbYaR3^E3!4hPI!#&0`67F*c2=E;I z`i_}!wiOlTSso(d9h=wLh9$FX&g&1`s>WLQH|Rl1UH;o5jODa91&7qT?#R^&-SffWpkdmwW+;Bh75M+j+@3E7`hop{-gl-R8YXz>+DS(>bx72?HAE#;3Fdjn*9tKl702(1BwnSkC#ETT4X3 z$*l>+9oqsUGb8~-7gO8BL6tN@?uZQE(SiVH$i}zeRIL^J2ryy;D92$`2l|l_bZh$l_mpIv4|B_%SlF< z10HO6WqY&Hm)ZY+->$!#H%k}52aX-qI@{7Z_OwUu{Drmc*vm2#23SitpaI~eR`_y$ zuyi&9D(NP@wO2DllDiO~#{c$z7$0q*xe0$)vSr(9) zV{3L6Th})6NGg!W0vmn$^|jk?n`jenyWRSO`^uAuzKKdE=qLocgCKT3e^k`_QJ;O*tSOUI92zXu>$+|F5j?)>iZ9Z_Fp z`>{G!`pFH~StvV5ai!!Zw6wAY?k@Um4DQQ+`;#+_=zP*e=9if6^v{BvSQx?>)O@Tb zaYm%sDUp}bWk2|Vg%bi&BBhG@AltOP$R-g&Id|ta>p~dZYK)<3K$tQzP=9%wuK#63 zq8{*wPH$d9og!{jkI<`3eik0Q5Cjs+I59QdT6FAf_0<*TkJpc~f;?NgW|b|SGhLnO zQd?9MdJG+7tuYErZk=H<=m1BF%Q~?<-(B5hY8o#PiD=p4*yf*ic`IcM6Od~x!& zlHL*S34NoKl-AZNME&8tCn2RZuJY2Y>xfhB%pd>8O7J~fj%v;Jt(&b1^#rLL73A%; zqM|}atVTsc%%+Y*Eep41aP?cKx3*xoGtopE49B=E7*#qEn8FG2rqF=6xE|tG%aOQa z8Z-S#g+-W69vpN{y1C-CxeX7$8&FZG01o7;XwR-KmW!*Y<@0CT%DFSt1eg4Ar`LAC zIEzY5vH*QNWju5ravEp+Frd)j6DUw=5Hoq&Mj zYSTwGsCUG5?~kSY5_|LMhb=QR&C(OwS$vQOU*quQtdy6#(V{xWx{dj<+8G*8@$9v} z$d|g@uGWduiv%lU*vYp4<-gnGcidn%KlrSzw?s>ftgzI$Fz^Z{$H32JS6t}`-u3f7 zwX|_5E}StS+jAjv$TaZf zdHnlp^ni4sWymCh2ZgMSU=a_)5_vJ4lRy9YLF?GDqvLRh3nfIqWJ>`qqpEGrdoS9I z$?sXm5hqzdYKE0D_`yt2ji&MvqCS#^?`u@`s6W~u)s0%Bs(tXTb-~KI-+*4O3~{*k z6xZUBV7g5~AGBTX;eqaBd@7wz4GjA+vf8 zwZW&HZx>$wJ1c|(ypN5|-c2iQ&C*#m_t`hS_nVGvwh4zVKf2N-M)v|OtP&7aZqpOK zlYS#kurq$~2W!{0uVoNPYsNb-yIV3&`l961-~F%f&fpEO_7)!Zo!XR9tp#-v$6>S}=OeGQgBBY!yVWQ&HfVFr4p4CL}Wp8wm3`1b7n+;Tq`jARZ)j~v6#U{rXV{y6FuBBW(- zr;qF?Wqpt4wwo)S#K7w-;ZhYZ64%4RzKs8OzttZMBjZ+w9eWGwe!|%{^TSuI4|A_m zyVe$$$UFr=+qP?OKf?(0fj|G*`lH5F9URHH(b?U_U^wQwR3*>OZ0ga(KOg%@BkypY8r;FPd)XtU3S?ItbN`ltHW1$Iow?t zuxUOVPv5QwQ&h&VgIMzS>~J?Daq%D#hL%`O{YDJr?j1jTvmS60tZ{J= z0uho8f;iYnIAEo-r0`Etc*X#95;qZAcMCeLTURf(Cmy`R+7YrgB)v0SFSwq3szBn> zE0b}777FEmEKDgP4Jkh7gsCg~Ars$$*HL92`Ov2_}`q9j;^nk*buiiBxo=@K+j(K49Ap zJ*P$VFH+jHcJ&CxC0kr# zszpY{5FQlHO9KQJo4_hm9F#=(ACmYj!!=1y2&?WqGo+-XxJR0Efe(4-82TYR?V8j$ zvAnOwA755a9`SLuzvwaLtnn!;Ewu+9dCX3~>;?>-biG544^{Sa)A$HRE@s8lFgOStFGQzzpqcIsD30tW*mEZTD1chwS zAyL&f{nF-445?c1Ss=Kj!|+q=jek92>20&D_sQqmnq4KAC^c*DUzSJCV&5J{O_%S4^A`-@n#Pv-kXB~s97oP*t*_w2G!YtDsVo! zyn*;S^$e3?_>v|}m_UdmFTu;Pv{tR)pa8-WNfuS%ss%!8_vV%Ei4YWk<>E)kOgmwP z9Mq&gRzTHN^1txlLI=~0vWO0WW9DC60GDgEJ@Lf9tW7FTyWwQPSg~@%vMaWiTiO0R zd-|ceA3b0{jL3pwlkESo_ZZ@1t7 z?|0^Y%O)h4ga8}evwOe(%{Oyq=FFKhr=%f@UFOUa!~u1IAPjx_J6dJ+OHb=Bny4gs zTr%&>OTYxrl$`uR$<510EDbQgG%x~_p)CB}kw=k+PUfn*!=pda?<$&m}J3d5Qb~o?ZIJ8*jL7zWL^W#qj1N zrpBkbATa^hyqKtNRiJy)>~oWDKzS*qJC334+kO z;4`vy#|C}>^wU0|dsZ;RMbxzRz&)2w*1hz&)NbD-GtPicYXU+VLf@748Jvi)yN*X- z379vIFWP=IlW<=HUFFwbctXzp;F(fYQDL$UCaD=JG%r2-w4TSon2H_=4m60H7yi?? z2d?!)89wwGysmWlNPbxN6U%NMg@xIoLmpD^e|088Zu0!zx-)YPQ6$@tPYFI_Q? z_2h7%cgMpu=HDs<^Fw?c3=DRoPY`b$fC(1!XU^W->V5mD{%&4DzS8|SvH#|yrVdRX zCBtac-S7>j9eqLT3inX0XjdGxxNHoXh1Hw@r0h=6f{1SzVS3@gp{EmqmYq_wd7W&9 zo4Xy*^BxQNvlc>yqDUi7+ToTl2q}L6tCO&?7AGf8*oUG1#NaE+qB0L!&S+-FCU$`1 zLwo7~Fa8H!;)K}_@un>dl@)}q_W*eh-~T7M@PnsG?upIF%WSB; z_)%wgZM1*$cs%2rl!#2L4HIuWRyp!#o+O=(d*sP`e=e8*_ieJH!y)NOP`SdSo3QA_ z6Xcw;&XGqRdsvRYVv-EF5|ww-n-iO(hym0LI=chz$Fi%Y%evQJQTK)+xGNlntrO}5 z8chG1ckN-uoW-byRtm8=o4YR9r z`lFcf|J0<|mB4ne(m?cGgWXcMb-jH5$G1yiQL#$iSYhq`KH1UYmG;J6a0hgw6jsj= zdrk=)%Q+Bdgx2xnnOrE}VVGTHQwbf)OWF_v;}*gP&pKOD5nYU`8}x6vy{2BC{p(#) zKKBF(z_5k#N5jtZ?Fo2yF@Q?KKbgijtmJS;Muvt=iY_xdVO->b6b&>aKC46$D`!g) zByl#lnhIdKxwQo$k)L^3e^x$^Td+jRr_6va;0h_2R4GZR8Sn?3qD$lqI6wv^!n()c z$N`iJKv0u4H3%K8bKBo*V@f^j;e$Qw}#kCRG3lQ?* zLE&KO8?5swVjj!Dl*Ax!7DKM83&6btOI0pZ3gvzQxK8wY`(>o7M>?BZWbf|nn8S$W z5hlrr?a{)3X*&_fS4AiC;E?%q*uXC_R!Z9h) zQOneeS&cecd3ra};VJ~$EgISg_#!6^#4FJzpM7|_%te3-&!RJ=0YRWj(_nCo6_9uY z=eY)c^B;Na5eauSiZi!bg$I-tPr%W}0O|&-S}8e&(gr{4eVxsi4Ci8%n5up>L$FI} zX=&mMFT9Y4^HGMkV9AmtlAMxc7+yFV|d>t^9EyDn%eqFJ2LB_+dA7);!ROM)w z;Xfoj)7>#RV9<|&?rvAqGsF4koTV5bp2^PcXoS?Ge?*>t)JV~?u!J{)g ze)TJLAb&jussJqg zuca#`gwdtMH>w9_B|mQV%J4EbiWk$b3_Z4v$7Yq+Ob4QLcMxva2rky$e(>g#2yTX; z69k)^uIdP5@9G8BhvikuQzObiL%)~$xBP*@rDTkb_y^(pwzsQYx|{2yZa0EUY+EZU zpM1;q`Xo~{1N5XJVo6`P4YAE2y#n=V@UFEayrpWq zqL09i2mvQJsL^*OAt^Og886z`QvXWD`+8?$^G-0Jq!^tb44o#|V5`(_SS?@v@|UHm zyi$!r9Eb?i+&P30!tjN><8^uL{=21m@mUf~%)$VID0uj|Mm9PIXa>7Ffm;WR71);6 z!QD|V)Njh7>I`K3n_4^N*{C{$Lsd4Yy9r4GqzHVMtk(p*`xwxALSN@z^{#P5sc#s> z#ZP7t^ntE>C|#qgF#1GPRRY!!CMl7Gc(_B$k>uPmnK^X@jc3{3^p|r4-#G zU(^Q=A&)H`9WuSLL}Ia&N_abl`I1X6(LOjlJS<=N%2(hL5c;5CipQg*S5-p{7YeMS zT)NdFzGY+e8cra{z>kbDc&`zwcTE+ z%1XfMgG4ERpZ%IZ5RUAk_z$L>6FA0tp%MS$Vt?;@bs666t0^TVGh)*hF zQ~z+d#S8=&U34*s0q($94J?A}Y#xGDa=SeE`yc7&;tI;d3-t5dAO;399GcEM&CI*_ zz8RBA91T&^(4rU=gIivei?6>%Qd2QIL*oo$K%;ktHBUV#rSq3a0PW6+r3M6)(_zhe z|6R=Le`wOgEc-NxI<}|>O44+KON;>jtUXhYApXh-^NJbr$W*8i63%Hh$)63X1Z0XS zB@W}q5Wg-kkFj8!N=vF_(%eN@LK;9=*BUs0J~N zZ|c+*{T=3$I5yHWH`Qub&xoGK#9Uyg9iWV)2?XXxX&}l+2dO~JL~@Wrftj@dS&?e4HX{vJNea`MNv%yvZPcO(J>w#-7wfp7Dl-ExCe%sW|jc*>+8 z8OBmBGs#-Gc#))_n`~VFhLkVP6R%Dp*?!SZH9gX(33#U%KobICFe_EPoh?8v!iD>} zdWYT)pT$KDQWd)-bSQ`ljxW^y!H< zr)W6J8%{LHB(ZlZLjX>J?5)Kd@N@fOo{X-tR?$Jg3R1lU6qnNJmsMhYlIR|mSQu<>Z`ukEKE^A+k~7Xl;DT1U@6Ox!`B6CKgCCX>7%1cw zl}d7Uo}?)g9ESiKbS`D+lSY2ScPR}NOsr(E28`Y!4WT@m5Dv)Xk+Ji7z4G|ukJD|9 zl$MsNWS5cGZu`M)$hl2!zWHWEf1_&6cv5dL_*G^P422!~KAfnK8fbt7<@ii3ktwBb zYY&uM+v~T%sOUGc;febd6$w!ZuaVdq>~I2(7Z5aJKz{ez-^(Yjzez)Qs#U%}2tmlO zw4!c$;IguQ4}yolbHXc+KV)7$z_xhu49P`ws&EDjP!S0*gnsQqrZ`za40}wVw5A}9 zA+t*$BS7NF$rm*r** z_PE=yoa{;5GoKVRIiYS9!elMKdZx5OHD~RLM7oM$;qBrHUSX%TB23y^|^@ZNQ2jj8^0Fry%m<3$pa`KJmrp$Ow#? z>4>4KO4Vs}W)J_p(0;Pn^2lJZK1qapAVTz0*xTKzIpIAcRb-Vj75kN)vjdf$W4mjN;pqXdG-#|9Xp0dk>?6^Mq{EUC_z zZuEC4>F(_tk_~UH(*n8U5-=!|fP&PRA|D$CJr;8bhJ&CoFGy=hkRil_>VjbqOx>A+ zQBuhEXV?Y~1Ew{qY#4RR!7B`AiEUfufm(T(fa5y#w#mNOVUaHbAWCgbQnzItB!i8b zcuC1rS#;h-GHv#J$-#t&%h?0)oX`zD;Kn`MWb67h^87y^5aBNhl~q$@#)2i1Q(P&z zCFStLn}euq36LnqA<7$=U_W$b0Ha!L<<8Cw}mQ zA4p0{irjF+4dcvv1Mm!KCr|_cVp$~s8UXQ-12ZMH#CQy)AO1cBWOz|-`}%+JF$L-? zS5{W)@jfaW7>o&2>mVe+OGhKT$L!d?S-KE0Yt3t~O3jAX^q#d@e8z<`dBz;cE2)%p zcvkTuO4{~yFUgwco|cWTzo_BqUC`4mpK*dD!r!(F{W}b=9XpzK1BA&Nbf0S(}G){-|x&^ww_>H{sOE1s~sPfU^gDaXm(Ke|~?TD(kZ z6DlM(Jp`#XX{tjOpM0{GYN)kNV#`txW|(b}{S&QHY3VUk=<%3UkSf}n#eiSR%uJWv z>tDi310sDwy6Z#W8$?NhaD~D_gvJ9nfA+JVL1ZX7R>Sk-!4drYU`W~Z{0N0g8T&?f1AkOY}(1C+fOAokw`K2Lw9Bqe-;zD)T(eONlcv^d!~ zv4`0*Toqxd6CODN13l6K{oTE5SH77L?6}YV*cW8Z35%6sO-M?H4lrES!*42s4x}Yz zNM>;vqOzSJCx7q?`PjAJ))2z&?Tyl0S0kI?d-1`$e>o;Skp&1|QCxYPOhSN+{oqRI{_QQ)+5zl(8ipq$D>Lb_?JA?st{R{h$B&AB4Y+8+YCt$n5gR+9FHH z8X`SGN5i5&)JWj2hk;32_ilmfxVz+^58f>cmq2GWIYa*WkL57TyH3me79Hj2KwMw9 z7b%MT@_RSwAgw3ZOht(3ORxEc6qb}pc22IuA-%W+INyhq-3A60oB--BEV-z+`KMik zFuzT*d-Gbk=iYl|+l!A{$w*?=Y?(BvOk%LSoeEb%8u1M650#|`P-IeLkPb_z}_b0IhA?h2GWxfVb}_=V}+7_Y03Cmb)<*K+6HA9hR%6*^(<*Z0F?EwJ})tOCDPD6 zB2%&q-KnUm!phOP^2j3(%RHzfI%8mnsY_vO$rEriFrc&no!JSs83MhF(ciNd!6yLl ze5k_QEDCp>*IjpAhTG*x&d)EwoU2i4Fbd$+3GzTB9Tgz) z1rcz;xI-Fi-2usL?RjcGfo zSBU|rtJ6re;Tc5B=ffK0mR+@QFuz`=e1L5Z(UH_x2!j(|<&qhf&a}|_#>D1mV1P`Y zf7l0uBj6aVi85Q_8;e9LfzbAbXPjV)84v*fc>w`7^ z`esONskX9r+gq~vk&j#=r=IcwnK^g1WEB=m?}!U-_l9H`jX8+vdKl@F)P!NENW}y) zLN+WT+7Uz|J}y%dp_7$gb)3vN!6(Zu{1_PEZg>FbkjBP(X>D$jEs#L|<=5Ze=etfA zL>;W{(El!B)-1Eyz%r8wWDpAK^b$v)ldAr3_0?A^6a4OZ7ntg0gmynj) zpzj(Bar$siv%L1=<8tTszpf8_=Bq!F6PKJSPk{L)I4!RgdNyXG{R|6FQFm?^{MQ%Y zPHwVfV~mJ{lr}LbO&pkzs*xG;-~g^T5f6gV6}YHld@4?M!pMg^K3Q@qGo-MzTCV)$ zN5viJl{Z$uF0a12QvUY4-^zv^Z;bgc4htZ02IE`;hw<52SsFxwEUK#0ff=@giDyJm zqX~%`WjkTJ!G?j6l9GcYmyx>PS* zCiQV8Qkn`cN{+C^L0A2fOFpa&uf4xRTv>@|jT981@1o$OxBIr%V-_3lOUBuHjH)fw z!qYSlyF9!J(UWA5B}o`gi@j%{A}Gi3PB2#6TL0l$ap zM^VovHb)BsB({`>c{`gl$x}{Ws(TI=y(3|GX7Eev&W*Bu?HZ{*^+OVb+ovFy3NFf_ zpDFK0-5*LSDBoeX8SlV>i&os!>EF=YDsyMff7SR(G1VLR>{}$G`qX>3L019*4@8GD zd!*M0!5tWpJ#V}!ciwgrq~N>d10TFV&id$QB)4KFbfgDm{f5o5V9s<%+>AuTD!-L; z4H1ogw`TQfy>#ZqpOm=Ne9#}R!+_dgk`sXdBor9dv4JB6vS2o-JN8|kP(8tcXB`Ob ze0+6|RAkd=ut1JOd${6?%T$qOKK3e^3|thFP=VJNP^0|gbBB-?Txx2hNw&*m%i= zPV3npxlHc8=U#E2e3p!$COC0ER&`j(vN};#A6$-QL#?3&7tqy+aE`6w$h2Vs0ccO4Kb&f1R5hoEf+EuKZF!m<$^sLz=rq| zl9823$yypIQ!2dkl3H7vqdJ8)XA|2a#sC{P1^{$$AC~N}@CT`w zUsgZ;cR3%{tJT#o8br;pF7|Xlceigq)`AHk#O4*rFc=UQBope@ffrf9x{FGCd2O76 zvQA{IP=1{}ao`;4LHOEqvcQ__j-Gzm9(934pRRN#MK7={s7fAjNG6C_G+>B@kZph0MWJ*u=Grvg}@9313vL!slNzI+v(}Bx&{fMd#d>O zM9I$01wZOg#+DZT`$E*mu6la_#xb!eNKcUJ0>8Yzrx)+ga-X=4)&-7O7cfCUy@3hV z%lH=Rh%4R!=xkA3nI{2P0cNmJa~7=fRA5-N~RA|Wv#8oR>8#>-ccYENZSQ6 zwQ=!r@}2K|N15OoZ@f{N-kWc}nLZxhS3|Z4q~SgXCxwVw2sIFN6zOc*E-yd)XIXyt zol=;YCO6)3mz2$3gdiUXw@Jx427_iyHjg`LI+%I0x?+`?drFN-gS-ehvAecLs^=|+ zBmG3R>j+`e!@9@9AS#U$6ZBE^QzLD)R0r5wsL_o*^y>Uj#Gjg%tjul%{hkqiSr<;X zQ?hch^*43uG|fT~ZE6G-)5LveSEqFKAV>l5&q>(;j0pGa*(1F@eONf4=mt}v7&j&! zP@_P4?d_fN)KgE(E3dpvH0Wv=zNF8UB1k||`3#*nQ=Q5Z;2fkmXkNziMh9wS(Bz-J zguR9RWh})4{&m(!N@Xai_9)b^5>kDO&zpBO0bC>PWO`=HFW?M2)qU1SwU_BC5T7z8 zh30MD;#um;M-Z9S16}UdUVK)XImI>tg?mDYX;q71`!a6(A-!jm2>@=_!@f7_88}es6EQ?rj(bLL$Q~06?hDR zN&^X2e^(3Nm00+}41%bUs7%0-W55Qgf$-rNq|wgtv%_NAH3Z2S;JgbikOVLes22=0 zljHArMqNyFo+R<*qdcAB9d?Nnjz5i5ltqDZnHSxj*Z~M zClrW${s0a<%XbZPYf_7e22pc#Z|6YY7i+;{^v9S1?(op8GM` z^5{L}CE)ZwMdFjw)Q4&xytOn;t5m{WS~f{0l@zOY1a&8O&`$tq99(rkV5~ed=^!29 z5KJb9I=W<%Sy!yr1gI>S!I>n?)Dcn50fBwT9MK{iSC};3(m6ct*f6k=3A2OAV*Pph zI%V^!XXLr39^s4d;y~Am`&OJK*|Zp5N^|!I8go&7f%j<0#&>@B!yjtye?}cGu2||yL>NQoToFnn2(_{$OHSDpr0k*(n7npY||7_Fz5#K?j zYudZCe>g1BDJGPx6Z0I<0)+EXvaY;pQZsw=9I=Rdct?}OGw||+N0~P2oA2U=Nkcm( zZd$+(;Q_Rh(#bPrE4&vpHn&S~N}&dFsf11|A&g0j-NhW35|}(#X&fti;+};86~Y)j zY06C5RKH7hu75?+^NOVltCrabPz8fJ)tP6Up$xALb_{|r?G*H|uTX94*ev__sUuFh zh(%YdVR*X{KOzhv2zgl|7lMpPMQJ(BO_DhoPMtevE|=(V7y7#p1G5Q-AiW`|PgpK* zvQpWvCg2D$VCJ$M=sg%H=;yc}VekmE=b9xC8?3Y1`bHq#^{Oi}-iysFLS-81ZV)<8 zG`cuuf$a}elHo-O6_s#GjseaKuOM{|je0E}k$UL2RZTCW?M+|9T{4^mLt?eLqQ&wq znO1HUH|8ljW$9#74VkxCD7wZ1`bqNfG}0s8#v1`#;R%T~dj`+gk;rVD6by0Wd!x)V zp80nG+H(y7DK7ZBoqGN!r1qIdWu(7TN~@>K>@zQw=AocGc>iDJ!N2`|w79bnHuN+s zmCu-QoD>%3BlK*s#KXHmI`pXAsvC+#iBtR&p9D$|Bg*KYrhr$2Nv>MhV7)BT1UGy- z1Y&}%gQmWP=kP3Rl8h`Tj#{svNh-DFG8QC`)E^EE_DXkKtJEN3;i@Mek~dy?TC$^Q zXkAB-_uo-J7jJ`bivcvuEQ<`TJjf zC99r&LMo@7B$t2wdMTL>^$th83_>akhiZ_vgHeI>eUOvvkuFJrQ66dg{($5ZdJwFG zP&%nve)q$h^!US2Pr6=1b@oum<)oEMc?Jv5CmPaWL0VyMrI2PFg__QUHvj# zfC&`pj}!L@FGj(dbnv^Brfa>k-5_tg$9lJ5ps!!rJKAMWU9D{1vQ-}a$7AyBbI(|} zW$Lm^rMzjU)WATF3`Nx$AHnKa8GQV58b#XhW?G{!9fJo}DOjSh?V2=@m}MVQrW8Ge zKSm%*_~74H;z$1R@x_40YxA-wKra zhoFk&PFBNsNapv-kZ+bGLw`3n*XZ`rl@!0kFPe|PHJ$N(g;-@6ZH^rt;K!bxu33KO zp+Cv=1*b}L8hnQ*g0AA~6sU6%+Uja0HMMIunxGi3TZRk89PE@hh5n)qzUHNjuRV6IyQ_5XV~bl zG6!VNK-uvAu}Y+o@wb4wej~dA5xP6A2+L(0?!ph9H>ZGk`yQc)99 zc=oK>M&dh~UNlqM$3(X5+@%+0fAot|4&S@mRxFqMe}1c8n>l}>EI9RiDJ-joB&!I9 zga`%#ooq5h1PXlF&uK{JhIFeF`i#5k`{cM1FxePUNC6L88JYrCx-bbD7#_h&SG}|} zH_G;1JE5-diahY=zeJxfyLlI1EAa?)keU!DZCh3$RPp_i0wa~ulg}4#dZ`S;BS1_9 zI(@2Fyw9u0@CiExDH}%;{^1<>Caq!(=$K6+3!M|Rm539R5d%F?4;g&e4}m=B8ke;& zNwHQ^n1rc4&{y7aKtAkng%Bi&tSSA)+F=x^zD~II#`R$K#j&esnkj6Up8)QA;*HA8 z?p-_JV?6+d7y9Lx1QAsI3D1!pAFH6F6wr*K>gq)Zks-?$E|o1WKP9buc1c@Ko|M5R zDj6$Rg++yO)zw$ZZ+`uMk~woOJXvILhG+T=6PSP_#(=hZ;E)kN1>;vQJoxxA(GP~9 zeuuV>HW!JBrO~p{;Z35>7C>c(epEsr;FrewI$l$YSTYB1YPad-iOpeRfRk%3=3yrR zs58Vd+DxcNE`|kX3S2P}``uUqX@P{dY1am6?~lmLB~!)Eu$|DmBQ;XOc9`ECUyp-C zgTMt<2M=v3%KY>Uc%^2CF<7&C;&n*epA3>FjIfykPZ+o(9X8+fB#8o;=ocYy~7Z{Lp7G5Bck^dI^01VB#o299#UUoot z>ZWgebDwOm9?w5}8R&>xrq7%$C6mg4KYCm6NHJ6+QW4>?rL#}g?`ji2bo%VD?B_d_ z1{2f^0S~b}&87I>PQ*$FGuP78D7zW1_O%z_f-4GX)pFd0UqGa%sS=-ADv^|IxI#0l zDD?7hFtEO5?GN_cSoH=*Vk3O(*TmO*NV4MPfyV4gre(?T+!YcW_|i$kAtxZ{%SF^S0#2gj)1zDbcA%K!jC07*na zR1fsg?RH0EU9Mor?zVZs2}3EtM)kD)7YfLTv)?ip0Aby_H?V3sh$v(+sshAoejjwT zQ3|%T{b@b#9}A#)M>$!3nn}7~aGQ`*s9E2#`URPURhEuHCm3FMO@Z;`DW`lu8D1NF zkcTM^Mt|g(G6C-#14;$|c3=oBM=nv`(#to8>ej`Dj4RsO%=s%>pBhoc61PAd? z=rw0*wv2Fwf_JFiHa~|`jSy8gd#H=ek23Rkev$t-ekCX8un8%|h z=F;d@llJIEB@Vu5(249UjFx~l7^kdWw~kT>_2sF^7?T{^A0+{CAn0x^KiGW(uEuJU&yohHcY`WqoALXupsCRt&MZ2Qo*5>H~Bq+mSE z!D2=(E*8h8B$YwWv%=v?C~_wz=XjD+oH5BMFic8D{71`ig}#$+7#js-xpaY$^Sa%1x&x*c*1Y}w%bAZ6MBWw|x7Sn~|*)`R335 zD3hnpmrzWaN;O=NW;(%Ovca1c$wrDb5k0{&--rn&F_y`-%Exb!srSKPZQX0DL<(n# zKPC~&(ePG*_TbK|mdv~gIeqr&52K}0!JmB#4b)kOReKORyC)D4v%Rl1V?jH*8 z!Njl;w66u4jt~t{u?2w-4Q*udoE5k+4f1$gk~R>K9B4roK|o(&i%*zpi%Y4BO-|2` zOUrUOQ6KRM5YoiP2LqVMLh_3U@RlkVrM^ZHg?*)T`dnH6%)`>rg;j{6bX9rc$3}(* zBnBD}T&c4n?2Q#7?B89@xxom>1A>JgbGGl+dVl|RKK30R^T%hc-`M;6rg-2pwd=qw zMg@(9zDF27rIV|s%0s`tUFM&2xwL0^q$HIRb%)G9ex4@M-qMU!m|`5$d%0QRI&kU} zSN|0TSZ|hE58ab_U{p;JM;H_Q03@~QaR}ASl{kQ^G{l#emGcD5E`FemPCOj+jfj^a zh0(e=7@8)bk4F8j?F1l&^Tn?A@nJ;{}kU{gQYn!9UCEC8P8S7}%jLE9n}6_@C~6-EtB>zEfdZZ<=ndIBJ6%Iv9rl5iIsv1*GT77o0EX`;21IshLWj5^3*j`hrJfs;o;}ZUBOj9>B6~(IraFI|dY;; zqTZ>y83L1IL%I=68^8g}2qf`A%sMEAqLh!ipp@jY9Z@<-?5I9Bb-FP_cg7|lNCB8y zIJURLu+a_`1O{)xf-7b<4jE+HVEC|}FK(n|!#fUo6ac7?U_E;08%uqGDiBm}pi0Eo zzy5V~-^TMJ_1?ffXE(KB$=e?V*R{Q=j@TEx@O~aI?%i{Q^-pTp-$E zNOiefjP(x|7SEWLs7E;Gz>gJaX##yASd&ewh4PyAYwVjbAm8`E12X-*tAIo3Vqyh= z`ni<;vtLGBiDJu6L1^bP$(X)K%9njYzaJce2Zi2FOfvdq0Dh61pl`cvXc%n-vOu^e zOLV5ohSxdKM?J$OTFIm{<-`+m#KVaSBw#UcW#vxHlCUEdVW%PKhtJ&+8t3+0!`)r|kEaUs%PP4ckG- zfP%vq)(x8gD(AoJFpJ~h&5map6W^JD!^eQZ9?343KjK0@=$oyU>#-!6kzu6kT`&yl9~hRso7QOZ z@h~9rp(iLKh0ZkE`46!sSoLnyr}lZI$a-XdWKNU<;=lriK7?BO`vl zYHm@rg|31q@n>^lT_ZMd2T%$uCMRoh|J$Q{O%Skqvyx=7YuLP zHD@>^r^KY^FNsgdoRO57>xzZXPj?)aPGb{-0Ze9shzCtMsY=w);esd&@vdG4fI+8n zmaG#iTUJ&~M&7@zl^;sNbPT}&gBr)>FlNEw_%tavX^AAm)!445{vx&b&As}&l0M@D zkbEb@IDkvXP=&z6CKv{ThW3r&3*sY8Zg9l50B?w51B0j)gtR54hy%F9YTLk5_?E#I z2SMCNdtrZ}vD8Dzv8ik}bJj7J6J`*qTP{|mnc|+FT_Y>)D z+#!?Zog&F))5VK6+J{P}f!_X7z5UBK-p)vUm{EFD`W*8VFM9ag5QehF%I<_ z_PkH9EzzAmW4#mJv11413bGpLT@3@DALqnL$-wrS54mcRu1Lx%o)uqQA@0ol&4 z5Y@(VU^H+=?SmTjG@^7!JSt4l2`IiyiW7n=081Ogcd!~k=7ok}0l2-x{jduwdl)H5 zI6*~l*V_wz7cZl&aC}l7d@{CZSDYw0z;wbCgX5I=V?7ZFPJmGx)Y#G9!XQ#;iliqD zW<>pFj;*>3h|(H6kthNVX=l*JL`m1lWV@4$@!DqS^3I%pigXUT!0@`o17W~Pixw)w zYlljso$5G>l|%Z_#6t(f0Pv5t0JH-@i=zJB1Hdl@a#0B{#sV(x8iv-l?b#HpK~eXBaSpH|xZX0o*oX2Az5H=BrK~@!r~pfDJu$u6*ClZg1VQD7y??hHau5OIWjE@!|C@yU>c5Z~PI zg?<;7ntYHLxWK4-5DzkzOarB4XaroU9fGum218JO6%Taw!tOY6B&LI~L2u9Hi3B0} zq=|?>93nphjZC&JL%g*B(PH4Dp7L&8bby7`) zLzS=lH*EdP!$rnoL(vM1P_9P5) zSS+P<79tB9qkUllKq(C8Q-&I04r3q0kIZGk@y^KVieGDVz5q2J(n z&gLn{HEOw!o{n&eFHKGW0|(qPa;LMUG^as>HuIdNSdt! z+&|bQGQI2*RBxbUm-@Ru`q7Ux3^66X(0SDReC|*{aey+wkP@Cu>_T^G_uO-jeD$ke z)z?4&joan86PIFnKNFJ-4AEfbDQ&hSvv2zi;4chmdVf!+K1MopFxXvFqqoA4?15zv z9|j9MW*RI8=}5E!wT?K@V^*Yt3u_YWx2a5|z+f>Lg7^f06;Jm;s7tgDEQ@FzQl}V- zbjl37@l+UX&U9#oMTUPj^Xau7IcP2?5^Q12L=a6e`})*Hn(mLbT>Q#zV6YC zDRb7WZLS+Dk5!tOxOQ!1h3QH}eHhFxyVWSH7(F`h!9ng5u}T+7b6Z<`_u~8~(2n@Y zWO1I|-mvwno=Gzo#v!7fJuNFRB*-CXM?A&}!qz=?0+|lRKT|*K%UqkGG#0%C7%;7b zyfW4U$h?Mj zu#vl97)j{s=>ko{bOQ9*g7m}`mGH(gvJQb>8k8%J8WqLC;W(FA=t?NsPOWz*_J@f9 z&Oj*P;8M*nq=tkkldE+<0{0p1eLiW0rFnf*i&P=BZUA~{4B1Ln)mT51IOyYtys=|o z38Lb>)ES0_S2BhLS18~N`udzRyxU)X`LUioEs8hik|j%oj3@~2SYm(3czK%#t*nKjj5HrLgdWwmR!40Kg7e*k zk$aPLcK4&S3&WGLBI1CW|fa_hoiHOz@mUWrtn{t@Zf4S$m_{8fL8uYrrMDT`IrfI3kO zl7bnPB!UrQrQ=m4>zZ||4X`om@tdqIFYsI1PVjBs=VJ^*;R5ku<>-&;h}l=D z+e;?+OJ72SHw?k&Eba#{MJPf2ERr7oL} zfIh?065j?+h^K!6e1`c5Lha$fhaQ#BTy+)ln;d=1st`1AaJ0me6!S(b0`tUS6$olW(z|1w)GWUpZk@JE7NpyGGiFO9DO(1h!VrTMg%~7AZxqUq zTOT||_Ur*{-2vdyZg++fZGo`M-|q_b^tpyw8l=0WrZ(JD_czSx{@N4}C|3i3th%+J zNRVgD0oHItRFiHUZJNk$5ZKVh(nZeSNx}l#J3Al6{?YP=h7b3&)ZCUld1gsc!Q{|T ze70>U1V^-hHJdlUK#{(nRni8!h?>&2ixvUf0Vq3RVjB~VgnqaNCToe34w29r}WeW|Ib!Qz74NP2o!#Djk43;JwrZJqXp=4M9^ zao0Z-+qV6gM39N}U_w@*DE6%23bq%xUWUJ4`5owA^y0t_$F_^#SO>{dI-JGl!6=Z>Jra~2L{{6jZl#{bro*ie2sj4^PB=)!S*2$9 zIJC~l0Yw*bptTSSlie8qh|AH}ZwHf$P@AtE%kIRSQ#!OV5f+D_RtvU*_^NOt3Qst5XnGaJ@&7VamYS{s46R zo?Q8wCY}@@AC!SkXWzEh?A^6H|B+BU`Aa)Dt*PDJ^q7FCyFk=AT?>NQef!KD-Mh?j zDEe)t%*>BUI-0xu+i|`fzLRdtY-wKTN!kAKnC$$E6Z1=xUGTRUic1VZJ{EzS9;cD8 zN7YocMS#J<%lyE214>>P);Wmo@5M;KLPK8z!aN+ur%DQpQR3lKvuV`}^5W0GDw9vU zSSn6BTb#KSz>WvfM63jm!Ql_@v5fn)TwLHeQ`QktkN6asI9$g~zGvQH+vk%cYIuTD zF!T#9X)^kt3;Lg2nF_bpNXNP-W$j;ogQrA3dBZITV|$!@;S=X86KSQUH^*$E^beCS z-+6{pFo^%1`dNLo;yW zkAE-aa~5Mc)C1LI+Qmcqg#i@5Vew@# zxrHaVbBkTci5VDO5(9q3ru9XjWP`S9bcC5OYwFNJTQmBH4Xc%e9k0JAa~7W=JwvgQ z3T4tH7($Bh=)Lto%!&-bLctxPk54J1BoGo0I)eAgrUbzDisw7 zVA0GW*?HLs&aA9V*yI?0dF*^}*Mx`ImkePd1FSS_qCONSN4#Mt0%4BOLqYv+x$N5O z#PW{O(eFcFY?EjIbf=^hP8LUeGIZIfi^kbJ!$h>a78{M;?+9@eWWYSBP?05UEr?5)5f#@lHT5zr}g&U z)V5>GWv;@aPbU_XRmZ{kJv={z9WHlxh%336dQ!!KgFa>W1WHu-w=ay=?7o-ZgEMF` zKvlqjASnoejeOA{gV(@rsR0_i6pI}OE0xR6k-@qe+5XIO{ms1S^O7^?ba7-9fni14 zg|$3E%ZGv8n!G82M{z0NVB=FR7wJbS50S&GQS7kt@gy#3;1$p(GQ%+-Zdmn|K*w%r zS@X1Pc<9&q&SjtdZ<&AcS(1+B)xZFoC4hsN>$m|p7ilIf++ z*yld?IW^e&>}NlFK=lSPx||S@*&W6b?ZXd0B9~tB5&irpKK~V2u=FBH$te*()E7(y zOlYWL={_9rVmTMK6?l*6{a0fpOYQ{0?}S|jAuB6e_hUDfq`0-UOSTy=D^ z5dgRh&a^4rXZIQ(z$pO$?U<`X?M=UBRt$2{tPX?HMn$5IK?v@}xt~904Q#$RjidzPfzC_VVBhwRgvz zaJHi?J0tk|7IC(=wMbFE>0e|<`13ezfjGYp((F!GfBnwzNaMDD^tSch38lZMnfMrR zV0^M4>i9JJ-ij4^h%FmS2+DA~`r!dj>gs-xU01gt&b{t4&eF0=6N^gS9tfJ;3F!g2 zqI3q}_(B6hpp7w~Y^hdj=9y`ER_n%vD6q~W)GdaK#YrceDNj9kpDerVTItHokOE9F zsUkQRs*Hq?>hZ=a@|gAn92o{oy_g!|_@V$>LXxi&N?eGA{m6_NGh&_d=Pz(2Co99N z^oRt5As`86%pr@#bE}H=*2Ly8FhJ~4x0T7TGqeR*x6LKY|t-T zao-xb#uITr5IV@w@u$^{$%1Y3iWStoxZ~ml^MCrv^5q{I%-D9lr)bi`_<~}4T5?7t z7?VVw6A<_V?WB+-syJioWB9(34 z$P(2O7ww*mf=g8wAld7#lhzF{$m{ptj(0^a{?r#_-f8DbUU8N7wJ=nL0)Eqcf@&yf zl|UcY{P2j9S;FAppze=!W2rCDVC`#P`p-FV}TQSS|qL!$hg+&H4r zuGg_Nee<_&md74@RFX}YyfREV@6+Nbf{$=|odKPqv5=XTbAql78tH-|MW$GLMv5EF zRWy54VBq(uqpMRrN_5e#=-0V-_d40}&%2~!&o;@eoF=*OXKGK*f)p3po}ia%1goVr zeZ!)W{ML8@mPrR+WYOf3bxwSsmQWXNhdt;C3^^P#eq6&^QFRJdg1x4t>)xuOvf7SyE1yiu%ZF?enns-+j)FWh*@Dm` zl7z-H($(SW+r2)}UAy*ot%LG2JV)BE5S3&rslkOeSJ@74e2S)~J5~ktoE>Y|z8-87 z+bS5XtjgTG@z%bEjbDn-DEf42>10<@&LjyWWCcMDoMA}aDV*So94xsvst-6g0O%x6 z+r3MY3X1iK#+{p`wX#ws!I6A=f=4Q+PSfjQgvJ&RCIC7iIzVC*m;NONNKOcxP-`re zXlK*OIIe*_5nvyW;2(vB9=NIujYhVk4zChNbW42-9aC#Kdaf5IHb;g5GNl-JMi}EA zP>y9qLf>#ex_bv@_vY1l9z%l^97XF*uUW?=pd37?7GaDW%yXQeu%o%)1>E6>tEbj_ z*T}97;ojEPpAU=-{s2?%7EK5p*d%Bpb9=NHNvqB29!zvdjBXhjRy)64=acI)wyeLa zv$64)c~w>OogA@1{{gnq8R98jR|ijR;{A`l<^Cggd_ozZZKzNo{!&C<2?Re9yE@9T3P z`q<~??72g^Zqyqf$pO<# zCYP!Xx88cIs!Py&gSsq3LhOk3du!#MKi((b_{KLh>979qw=#9kNn(d_%`hTUIpAU~ zIgSjjTXNFk5T-OnlHerO9j%CMd`p>4;_qO!gl9OQ0;g>-dLkqwkpD23x#zol?5|NUJ=+gl_*z3DnE$h;(TKlXJ=o4r)*a1$4T1lkyA(lC}& zlcIp`mW++Ob9&ANjqsHtiAz0!LJzb*Us| z7QkSVew9h{=z*8HWx`P;j2;l52|fB~%um8h@* z@eC7i&Z?sTUN@E%4hm&1>OC9|!y=LZ1$uprFODTJdUIlPm>57uz;a|i^oR&KxjDM; z1;g9b)g>FAdq`3XE8)X51%opOAie#TjYZbU80nHB4j3W_h7N&HN29C1cBA;}HviKd zSNPv;BZFI*z?hlxd)c?hVem(NSInr_z9D^`3$nW6Z-tBWuj4w#({QA_vz-J^CQq)u z_@RfEH;_<5kI_gtc;ncFFeVfv{I(@vd{^KY()Fji2YpZHx3rxy*i!Sg#Qd_;6H7t- z)AK?BS7Iax<2EXzPb5ep;oWbXhe__h|kB^c@)gkQwJwQR&G+x|60uCX_%GgQEd-5k^Lr z>J4OODf#{W_rI@uGQI5Ie|hk4a`_b>)z6)K>8EAUg`bpE_%`N%n&1pcMJ9CoQ{xaa z7aj^?kb5&n1gXYysV=?QVIK(Q5w{F=Hru!6->{$1BA2E;I}xfvBpe*#M!K7v zP%jg2{jO(1UEM!u5_vXS3KoZ5orOGF!iZ?n@BNN6oV0um;H-1c{n++xTOMd{X~K$& zlJ;=No?VWV$jGhjy`48PchND5W#>=3F0a4KV2y{s`y6}I_O)n$^0CtVl%IEQc=CJk zjn${dmrWISc0s^rcRLx!j;)Y1Du_uMX*Jv7SYXC!U*M$Y5=_*J=YK$+c<^pncKK(e zJ3mdza6dgQRZhF;0(k&5pk&qwXvm!3yjMjYo7;b%V`7gJVQb<(gvf%V=TX*HNkupq zh6W8aeWSS6o7fCSnFJ>^ zVKAEqPVhh|Or` z%O!{E*-*;Dwzb79roNR5srt>n(G*aY;M~=90R@)&OD%U>X=un8}c_Q+)2bA;WhxfqJ=?dIQxZDCs4T z>1D*9Ug)j=5bnze*L>^eGI!BwlAD<(>G5{SPLBtZi!wuP!x~I!phgL;Vd3eT4V{{d zAo9(Uk{3Q$30O1+k_jN{-Np^C%d!hEPy;x;#y9mxCY#XR+Y2uaf0y$y+~)Ca)ZRtzqY8>)N z!!+iBW02~I+*Wg%e{z zDG&Oba_wmA$=L;ZyRB}wbWg67L9E;)#Ky?Ur<|$`FAWuk;Z~3R+w{k=sZAUo76yQK z%j4J}B46$=zyM{6L3Bb=A_dS*`~mR{`$%wLX6nbD5}XNm2N(eHQ^)WyHX%%(I#uF4 zaWV`EO;^7cHf-DVx+g0SvqN+l4ie}{teAZ<&+8PMVg`wQvdtF=_jI_rYvA&wamycK zN*8~zcI`7%igheOwXGOO1QY}<7@frj;$ma&L>{m84iCpRHPz!#{>Tkr-{P8U{}x-8 z9|hsy=3D`KxTnwe6tp&;DzZwxX0RtB zl%QfyMDch$faZy+2FOta{CX@HBYI?oPi9Fds+4jtw{R^ay|tTV%RhdlzY_THEu3+J zc=D^nlbj6$EG$-InUG9e08FqQ3{wK6z`^#tvKa9(oD#fV(?9pUd*o-9_Xc`v zpr2lz(?2ianj3DC)6Tt6D$5bA3=D1}!U@K@Og@-vGJGN6ft76PnS-mj&vrpP}+1En4a7Yt+BU29j$bszg*7@fsxBrMVpg($)r8k_aBtbDQt?HB>W32(6aeYzWC zK7xp>=S01pwCqDtRykQ7{qyhSx%+-3j_3X^ORl&<;wBx3dPf*yNVvn8_@K}f=88My z6@Pz=^fcE<=av;x^WSdyLb1Wmo8oU$c}aEzVGem zyf%5-Y)Q?`3wR?gcu7Pr#90023X91;S0UI-gBYQyN6KJIguPqeke(AykpW*E7+x5T z=H%)1katjQR56<1cNHH;vQg>>8pFDv|8l|zY#-?T!i)&fR58GS;l+ey^xPZ-&9Z~~ zgd~|IJtZGD0Y`=bRtQ~^Ik4nPn0LYnkO09Y7nt4d?g6RUyhg9P;2e7p&lx3oI$fuH zgAyI;y>S>c?ueY|N%5iK;81;yt7psW-68M5l})|=ze)Eq*3wX5g{C;ZHXwW|!PvZc zb3Jla*VWZo(%4W>9gp?VoNC)0U%5W2x!GUh8>(yX-a{s_cF;Mih_6|@WL1XA7CjdL9-b&5JZIwst}BagI{hpGZvEqrQ1g$Ggd*zVyB z+>=)*aTw@wrXDXntqrmlK79EjRGoajBvl;`>0X5-rDRJYTxQu|kk+yBMOpc$JM@_= z|K~QDyYN&=%*aWy;wpAP9uii+jAhaW&F<6$Ag zOU9Ukl?7v6f-PINY@d79Ge@%LcgW<@4=>dlDCsRKDw3(k%|t()3#a*pIBVK?mKqh> z0gyNTsag{lJ|l22GEQ@!lU_)8A$29gOG0m6v~p=(Frz3Z+g)vqdb141GXzRr6$RS1 z3@*0s*s1q&3yOe1xA#_K_Z! zzrE2uxNB>zckiz6Ky~3ReH0HbF%nJELi2j`#=ql^t9#LMz1mP;KhjWF@3Gq)u-1|{ zqStjy7*Azi5uJcgK=ag7Pf@?~y7JiAN84Y0;@+&uv$9f)s{=hT$<84(P7i1d)orL| zLpsDrd893zpt-nG=ZTlJ${DiakGIQ-=UgUzMJa-*om5qsemH~x6!yd%^k=prL(70nwsTjdnOxTyL(EW zd-hq5vYpYlEaLdKiTpd5W;9l+Gx>E31m#j94Ub41SyT=Vp4LZB!j8V zD4i@cT>Y2c^ttEq8g+%Q zy6URYbm_jx5Na@&D31O{??w+SW^bSCl!AjkKoUwd4kP&`b4tpNebk^v15<=uilcTI zND<1*u!;a6j_BQm0F4LWD=e?AHionD=>Awx?EDViI z!?+L%*!YOe(I*nqKV_s$*L zrny}Xpk$QhM|H)O3kt(CD_L585Z0S9K!_8svw^rRyr%&E_p@My0y?@HpRGeDTHfUJ%0aaYsW#16(S_?7~_zb4^akG`w+M zhNGCh2$@}^XTl_}SV2VGQV{a|wsYmF5jq#tBo)Wsf`rxD(k63YOB+BkAbB{#Q3N~&i_uw}RO?A;~X*S#Ww-^G`H zROY})DyMvwIAh>>ff8MSWt6~Uoxw*x#INWy5#Qhx(H-lCgmFM#dhQ8%{IB=%aWI{x zdF?OZCBr*q$`l!f1eh?EBw~;Yms&4dTq;Y(pr{PPy|JKbJE8LP67!bfdC1R`~(6oJs~&=sU(z8 z5+ETj33()x05Khmg$wRovSjt%`>wW^|NHLj*m8jwu#IH)NHeoLJ9FpGnLFox_uNwu zna~1RXJuQqK&66v(O^EoY;F7_une&J*uPIBGx*}i{WEHX*$SphW>_P}&t`nx5cWAN z;b2lAXbSXpYpoT#BH{9Fk6Nu6KWp_%o7C1CNpk|xcm256{1d()l^EtIc&vo7V+LeD zJ3>F+1vFng=%G!le^{C0ty$B7&xI3{+8%A$^2XOPCeKF_lnJ3OGdyWvi)%xAVwxLL z=JAgT38v7tMzb1LAlqF3X{U-WlqlKR*>d?6SI7(h{a*auKlwcgxy6^^LY;QZg|s%{)=8*4S9yRPT0w)#+-Q-?U-n>z=La zE%vTDi_Pi{c#!nn1kGC_07D$w%1|f7V*qGDatKruVVRH)I8J=9?L-1VakzWL1ke0V z4BEE5{jyY5?v>A7{drltx=8-|=f~xS&mr1_h7o~>AQ{eRQDLU;89;-5CA&*xu7-vZ z&T^QNiooepv)QDxZm<0Hci)#k{OlW&ldLP$4t8QNcxT8vW6S-6KO4t=+%4-*kjUkL zd-(_jhoCVJQnjdvGFq3@g#9E+Zus(H4$mU4-VS-^#i!)rE3Q!cW(XJZ(JqIc%i;eRTLNRtTGQeRV<3WzrDO0D*V~;&7o40I{uipH1 zsjsV%ZSNIH+2;4e+*l^5u1=wy4js{8=Bhv>XD4ZhH=H3P^bgm)PWQ<4uG`FxBR zYc!n-$bW%J8?p_t2}ad%$LOL*vsm`Ag@uJw=u1Uy-PiL+jk;r?bgT4L?69PVoDgy* zp<;^dghZ{cvO8x-&+ug6z_vASs)$T3L_J|#*sKhF=E($GdCs=*RV1VM4jb>WDlE1- zVh-@#BvF3re}hg1f7JuTc0chzj%h%;P(}emMe69)8eVHKm(#CtA#}QJ)pFHW?~*KN zQ2M+f>Fn;65_AM<`S46eW)@wCqK9STs}qDBn-woY3i37i8p~~+TZ^hvGIB54UB0_) z-}IOa+v%~+s3&`M^nu1&88ivt1sBRab4yDf`bt@94VGNe*H!!T)Jbz@q$6})(2)}G zgu+NP1(B+N%TQyTE>S4JX@5yKfp{QOYZy*Yuwys-T;i-RmtE`M#qH_zwOekH&wcJ{ znZIBzQu3mMfNh)u0As@FG}&0;guN@K`vwat-z%VLTyOA}Jfve8ZEX$G`D%O{dfR<~ms(a3TY%0Uy)78u!4f1e zY*fe0o;62pG4{qYQ6Ckb+1$!2s@0CYMQ_SlEZ5xfJz0Fg<&v0F0970SX}|*jswNI` zG5s2P3AC}b;iCp1>y@$DsfZWskc@frWX6oCa?4FO$g3~EB6r<=x3pKOD2Xz8{^^pQ zkKq1@1QFC6a5S-Fu#Zq?(2&s?$b#!J0SV`|_F?*Hbw8<%UMGMWYNXAfNCpgS$^Ujn?M62oOfEgDC zh8Yg4oQ#ZXk3aE*m?;x24mJ4WJBH@3-sNG%oT2jEqD(WoiUWB_FDUT#z?}!x`~!bH z=-AlTLpVUjv*BA1qKA~43a?FcQvDvUN+(>gYlBQV<05E07_1r~7aa$u_9!W#35sy^ zI8a+^>)5k(&Dbf6FI>0oKhEhg-L_Rq^f_Kt>abj?Q9f$k5Ust@Mu+9i9OX*0v*e;W z&IYIZKhi(2LTvHh&{~@AN}V)4GcjYN_-*k4KMWzM=sW;}9OcS{GO@CRfNGfKSE-0V*+Z^V5iH}$L^k1DKFb8uRiybY<+K~+fo{$C_FU&qTy4&soGDwrrKNol~$HiT%>py{Qy9zcPbXq2trF%DLJky@#9 zkLQZY2v8&umJD$rzZU6f*N{HE!&z1Q)7C)X;b>iS`;Vy8)A6j|aJUx0Ze4VCqy7D6 zTZX}XP%g6(YHzMw`Qp-Z&N;neZ|Uo`AmYjlPqVY^tT{zr@xbf&=^HggWQ&T!hJ#>O%GvtI)4<2*EC@ zdLek!5uc2l*;lWR@_{Xr4Nn;}qZ#Sy?t_~Y_8PpwG@DL5M!A2emd&X(I!|D&zOzH& z2V?podeZxDXd2>k>;B2($Bk9Tb-{kOv8GCWwr4WCnuZvpa8APu;zq{;Z^B5b-xcbs z+OBmLzxzyUzkIH_<3CY*uwf5&dEY%zjat28f)4PaA7h&+2h?1=%297J1;D7^kFF^B zM_X0NUG{17Z%dglRf|g-844nVmydJ$Xq0TFYAOw%0Z-H(u4&iGUk5t?eGr#f4u@(i zgK~iHk^Tl@t2cj?$M*uq05oB2rjDg&G5`T$t$L)tuUEEg2asYyfhc|X+Aqm@=P#8x z&;S+`6aW-aJIFT+av$0siXIK`8a0r-`Hqf0ReR2M@E9vXh%v4#fm#sP=xC~u@*SIz z4B-)}s;ZK>RJ)vc>u)7x(tPp6r->5+%?c9-Qd47-%s@y$g9z9t{urfU5~3IU`q#f! z8PSYX!^Uw#V@ugYa7wO2bx4y2)SU>6q(2*WmiQh2)P^&4u?HIO#~yh|E?l-uMvbO_ zIDW=`lT=({FuJd|Pu^VdtmK??omeKECKK}J$e6iHq-@o5^1xkRmwd4A+;9F;Cd^zQ zIivH%9-pjC5a=`)!OWG42aM;>c)`uxZplSDDS~a9T+j`N@^3T-6kIO6_#*k<_kJkM z=(cX{TDk9m2c&iTdQ~5Z&zD(?=1FQ=hD73$;P3;}FVv5Bg;ca^VVx<8Rs0&<1|Ttr zlAZ1E!xCGR&O4odED1bCn+f24U}>yuc1=(~Sgod@J&ZhZ{e4=0RavB`wB+|qp01zb zbmWv##KEa? zH*4xVf4@D&7RGxK2A+T<#DE-w_oy9j)t+6_-G45!za*%LEo6clCP$XUOdPA5%IJ*Y zJF2%&{rmpC`@W-{Dkn}H#&)Z)n>xo}H_OmbkJ=r@FgkA0E#vua>7>5_>JVcOPUo>S z-x6fOjPoE@qo<;Aa^#_e=%Hl|`916m5HL@5(7ZV|18O3u zkx&f;-^maH1a5aDA}as@KmbWZK~!~6i(6K|lLvZpV58#Hn%<1`2DHEH!C^;05ro_! z+EcdqkH|6pHJ)1tIbU?*Oq2DZ z?4n%X*n_$Lb1$^v6Q~73g?Up}z>bCqMb;{z46UR-KNK$6N1Dkxz zwpy6Lf$bHL2Q8R_jlREp&B3+B(4nKNffF4Fii<**{0AA)v6c{!uLc+KF< zgzND$Kxj>?Q|h}yl8lgE1l|Nz9`}GayIZ9N*{XJKSS4>DixDaJlndmHOTH=b1t*C) zAr+};!7MMF(CqO@qJUWy&;ZUon5b!@X$_s$NbHb@7J(U*VHgOT0Q#x91$V>?_i+7_ zA)RrY`i1-T!MY94sizCG$KEcvVCgc%{zgKFL7HphUJ))zHt(*Gv(LOqys!`V0%*of zI7MdVPnXH(d`_y?y)1wJ&G%LLrxuQGuLYu|fMUU}se+4SZM>N;wb zIz{qkj+eyrOvEZp6_YIisfY=6ITMEa1*)eL86Q~??NT`jeTc`WA8G)6K!d;V4Sd87 zeq&h#z2rBVMkvk{3Y!O* zF$f<+bc)^2TkIjj)KnOb(pkuT!;@HlihmXU2F-{-R)Yf#yKuUN(dmW2K!>$xXzWlF z_@(gUULL7;9~9jD(;I>T8uV}fojcGLAn-d$Lt0f*H|=+KY!aURjkV7jrfIdTu z*dpn^zHslJP1er6mA`8p@O?|20Q6FHVhL3j8s{F|n{Ml2ykpUujcpF$fDzHbNY%^^ z_ma@&HA{P%_Wm++;`~{eBgY~xQfi==Xc6<>R!A^HUbb3J$?72Zka7>ZgQNO*fFlyU z(J44A@I=;-c)*PKsy??RT;T8y+* zOji#g1-hU?qazxfst%y&*ZMBEY%Xht^?F!(+iIi(v3u((%cOM6d$M``s(q&{y!uW_ zn>?1tG0pydWW1M#zGGC*wm?%q5}iJmB}>kdZ{B{J5PVlvRv@axcG>veTFA&%Qr>|%FC-mF&6^h1_G`Z8 zYD-6D@s7s&njhdu-A)%VT4gJsTEnD7N)xP=dx!Lp1^d}@{*}R+qfgJMTT^ciMk?h^HN}Af*#222l zPp_!5M54_R>KcIaaCbuna<*D$CAYvQ(eIQ7Ix}_oKyKq7Zv%Z) z16(D^=MMFjZMAmo-SDf{0ijw&Jr-!rM8i!=b}8k9MCp)9!Ody+V2 zs@SsfF*}lsX>XVeK~|al(O_+OZ`D8+Rb+<{Lga?QWC+E<`}S)DSi_-2xC!zNS{o8R zD!%&mi|qp{Yt)`wC?=)7sY?A`P%u_)*{zXuz=^=IFiY65{ylvkQUfE`1Z118WyfrR z;;YvJ4g1Kcl9e+-E}DIYc)MGqziF>DY+oZg{_rbxE?4R3Hl|;2mE??>Bt;|A3%G7DH=*%T5{pyDG8)VhW zmGb7>Z%S`Pv2;}Em*X5k5CfdV@iQcU=6n&@0DD!(t^a-`Yi7lw*kKKHwFdW?kT@a~ zj0+5Ck+x>7w`@<#0PJ)dME)2plbxdpV3%$dG5U}ku-omo4GatzW*|ovS#&0nKNY}#56=Y1sC6s!x9qvC}2ulquMIkE+jQxW@H!(Bf$*tjV|K@Fm!`? znMzuu0|&@N90&8WF!GH>f~rplnE*u?t{bl`9nn)sS$=j0sq?1wlmM zOv!kR;MYFh9fk{NoIHSy$J5y@Q)kSPWZ3fbxc$Nyw4}835#r{vLTkgMbf~Ag#Of?v z_q!Gy?CQOoejDoe6JTXDCT3V$eFEIiCv^)-U0Dd=TZF#9R^$(uL;k;!@4fKdq`awj zW=xtBXN5MbTT2Z3kmoW9AeHTK(94c*A50AQr34@3fYoM|kz>aJR63=(L{E%o1K1>p z4g)2vUAI;()TJ&u<5a{~j#q`p!CZ&ot!!{eqTMZH;ZnmJq!|QKm~#fDbk!SDs!xC% zQlSxWn3{Lh*CjJ|l33G6i6m!9#GVYTiKeuWet=|CR1-~2AH!QII8C4n;7e^q*rLy> z^!Dn0lC(KKn2desi~-Ct6(BS~@WIC(|L?jSp{U`E6*Vz_s$dUG>WQH9M3}Dux9r%y zQO4#V*+(?cy>XvBmF1Bq&prBpO_qCf{t51^zU#xTX(@$b}#O@IS8{rG$Ma8#4$Sfc(+B;p?DY* zu_sQ|QqyKiYRYs+YG!IedbU|hN*B9531ZO}@gvzirU;dGnAbamxX<997f_kP9SrTq z^lw#Vl{!4^U@Sh^_(VLxU}cHcU%c@T%>zO+2BSdz2_91Tu-#$YPc!b|Khe7|_6^&c z`lKpe1c8QY>-N3X)qO1@KM2>AKH==FU!F2{&b66ir&}Y5X(1Oz^$cakY;A{Yst4Df zjgJu)2%o5p9RR?zW#mcDf-FfJI};(MplvJNu1-r#PLoNeo-4_t$H@SM?%RkrEj6eK z5-do>&Q@(QJjgp?8 zMlRvm>te;Y|E5NydB)>8XCh1<@Ee`N=wzn*IS@kX5SwOUoZT{mf7DnFpii{m`IxiP zB|dY4Bu$tvS*KkpQ?I;3ES`R`4D`xCe-D%jZV7pun8t0E7ct8v1Hg_QXcx+!noyJN zg3k^7M}iTFhbjy<+b|H83733L7A7Z(2T4g9FtgCxfp&%Fl$H;mJAJ++W#>u&CKQP9 zsFW5=!lFO(!5n%2&pbAWK^@XB1ry5A>KlNNDBnZmRS4 zcW(`Jwr@vtz%sl=EjYXnZ5R?+Bmr+1Fko_@SwfoUoufKJ7wlcJ|WL5hL>xv*CP`l8G2K zj({@)s|c{pK}{Iy;>X$#ZBrbyYP8=8p#@5B6+$1KfzDQwc6d%#MMDLJ?Fo_^@dUhe zrCQI{jn6iF`@XJUTrvEF6b#Y(<9o;@MjxL8`|NvBl%>rpHR2t(&fm565nog7PciL# zenRe8*gd9UY==p&a1i=GcK3uc`X|2M`X>S$!bE(-E6?|fZ$F(If=B@yFxkbNGgd}r zjgrjCv!uVeRGM~el;+A(Ny5Id(`Lz(C09tq2K!2YBP|4{G!)1v4?6hdXIzbz7U~+j z4i*J!5z-0(Bmm&b+F?AY%&JV3Lm0VJ4(UO!SQeCR0DpSzP!?xf6h%7@UIV3svEPEJ zZ{#$VZa8pJ17MhJMNd$hf`S6IrG|H?k&?i;Rc894-81c!J<#wPa(i%n$p(zU;Z$fv zQWpS3(6q^ub?thzQyqN#p3=SQD^lQ!2hWIH)9p|$oGmgu^akD8TRXO^z#KTsP&$HY@daZ7}54{~tjh^P}f4f|s=Yd_&OqE7Km3Qz; zb+lBC7}V1bWkkO@yS{1~P|gMRk(r;@MvkACk~`jPP0b1WZHZwoBmV%yFqStR+-NZ7 zLDg({hp9MG^1&$YliYHYkAIqZ7_z{ISsyinG^kz{bDY--57~edsa?}jF;#^V*)Js| zLGuD)dNz*sxnFT#?fqm|1i7?cp-AH&w?vz~StOr|#G8CUb9aZf| zQsmjK1BmtoYTc`X0_Zq--aKl?V2-twHyF7RtB%4#lhf%mVIRJsaER0roQCZR1p8c( zThrrct0_CbH_3W~J$LFwN%<4BG{i&=IZ^{I7{>&tYC?zOwZID!)2%c^PvSHoXzsi@ znA){SYg>mDuX#nrW4acZr2OvsT3g%3qP5Ll&sFL`U4|R5JG$$H+@Q579-ojm_X*q- z8yXkB_ogn9O=XoM^E z$1UG2{X5qv7Eg=TV+=Urg~m_I%#~4TnUXbrinPGacEfXzvJ}Z%xK#2^TPmqzri(WT zCJ1~b@Gb-(A^GlVD8q-?lq7->0w1NEg~1RTgh8rS6iAdo(O(V)G6$Z)b18_S|A1hI z^BQDBgfmv7r>SXkCE$z;4B8q_YeDAh1sR%xL5F-|AHg2nJxw(5U?E#5mpxFk>Kd2> zt3{&@!b!><-+&$fWjp{cNevn}AB6%5`n^7%yz|amP`b}U*rZ(LAV_Wo)OB!8)hN^o zd-=Ge22s_>fpSgYvTNs)uq_G|KqNlps(<5CC z)zZ6Twd{KBuj+!?7+6ic_{$Q9Sf(Zb-5}ah1kcH;+J$}%9;iUNx^rFw^AfmEy=uHJ zuL_XM>!T5B7E=h|K?`;?N@L}ooz99qcjJ9|NnKE`M5Uf(zYqhuIzwXX55WNg^dhSq zK=1OiSHE-r+7VXkg5(La{MM19Z1u1Rt8J(k%V|?&)@&jWfJn4yAKEJwW}HzA!@8CO z*NDj;fkjx*;px((r%h|;3`9%yyIM!j<9OR%YC90*DqMpSO+avwBEAv_P$5#-@545H zMMF5h7~5iL>HO{Jmd>;LYj%GpIdAHDDPt##J#A#bZE;xL%6*C0Fr;jV`8ILjJ5)&T zCnzNG+D3g#l3+T@;0w`e!cr?NZLO_dYehwc4*-vV7jg+=ff`<_gF&?6WzRX3NQbx- zrn**_kCdPnL^W3JayNsEF2vFN!nxVs`!Rnf}U>+u}z~`f|dADOyraj`$K%g1(U1 z%9y%LAi=unz=1P$@#?}&HC3wo5hHSfrmkjN-NrSw1yfJIsCnz#QW&+#R0o{+D?W!9 z9eoZMgC(mhUmgxEU;b)+ef6sY_0`uU6%^c+I&seUEI77>?1_Pah!x7a5d9s{HYqOw zEumc?JfM={U?PN|5Fwahfb~9VAHtv^wF~C<2>O(U^q@=ZM10tbFTPmC=B4?=V4K(Xzuqzag>_VK3Rd8g587Qn zEb~-m)`Q<5+!sM41$<*|jjC8y&d38QXn^_FmKOQ*pPrQ2g_lbNku9u_WH__-;2P-i_ter=JxYhRSUx(Zc+(I=lJ z8F>>W4rXK?IQF_Axy^WfHa0-=1T^^ec@=^MW~pTRbv&rxCg_6Csbj}mz(jvpk~hw)`h8`VyhSjJ`4x;gWl!->4jG=>E5<-Q(T;V zsv{+xgD9=4rdDa-9LVrUBA#KJWqV~CCa6RXmw?sZt3}$|weG6j;;G;LJYLTSI)buR zorF~(OekO?qBN7N8C|NHS4y!`;Y}o z0r8#VK2C8nE-yudAK)qo^Mbgt`pb$=gMt~R3<<7gX?*7?L;&3`s|GURq}7X9 z*g5+EuK}^?sJ3+JQn~A{yJQ3+OnmvvUltp{@{j?&gLvVEZ7%HWAWsM-dB+C92O7od>WkbyQB)Ibr{Wt4#hsaD-N34z(*n6+N||g?-F^^r#_%H3vuiTk6Zpt@P$IVF0fRm6HX-d+DPxLH*7n z;N%KOLpkFIz;I$(NrUHae9m|olQmkhd%DHdQZJ30-jdehHR`O1NTr=N{R~Nm_RgA; zgOEK5N-Ku}pt9Sgr!dRaua31Yl%iMsZySWtf)?3|C;)LiwNm!NBT^19l>!gxzMf9; zcn%B)K@dn#%j{}D|M}15_19mQn{U2Z+S}XZfBxrx;8W)qLZDaYh!5rr3?Bv!5P-YE z4}I`q!&H|k;F4{t-;|f1`HOtv>Z>IY$sr7)c9(LVGJoaDx7F@1-TXiD_s4!GK@3u6 zeeOF5K{go~i8(ig!oeS2;&3g&D3iabYD6o;&kBfBjSKq$PAzgU!!*Z!WR-F@lu38x zb}4)P??w?adiD}Y&dV2bMw(dQ++#w7eLNOip82N$3{VzZ1Wi<|P#}akeR&Y+ZH9v; zUJWyAxYF0J=PcR$h%X?&X&1q4?qG*B;OH2|IB=9XK&-&z6kAJ5 zS|&}JzO<{hbTi%x?bX#A!oAJ`gqPN5)0uz=!@@`!24+@wmo`vYES+T~FPluZ<-iAq zURL1^R55f6a1CIS0?#z_)V4nUINyhFo;3ZWl`T8p{YR2_AZf(-nSlW_Krgf$`^?~u zGQU1jacU}(vH@p9`J$69u`qS1zS4K2tFz0g0IxB{MX|;XK)22MU?CSR^_Xsy5XBYr zD(jb`&|~k-*q{kvZ@^Vu0?qE4O^Ml4FDotGioP5pbvB4&uPJ5q)X0d{!D6axs-&~S z;&64~W@m5hy&2V){;TedP-Lrj-DQU>l#pA79e)^AU;EwE@l$R|89&{YqE8E2_`WsS`hJX%>cdW2#=NyJ70fakMuRxO2uku^RU=)+^91? zBN@orm7F_Kw6tu5t4hS%Kr3Gbk#w*LkV6nmJf*ahdL`727-ko0AddrB%VZk{?(G$_ z`)_wkec5jL>UVyQj7K4P_%}b^7q&)KGP+`!6o_-?%#mAfy;UB1=pm))^?JQXgNvBI z0K-E`(>vf{oCf_tk}n({FoT&5kD~+5S1X_Ui~Q%Ge^z%l4g>E5Xx>#qO#)Ez2=_}( z_cQ-{pUhoynOt!7Ei!5>QY(M&W@#+DM$Y*5ACR$bF0{qqCQP%)TfH06+W@ak;#22m z#dQU40c_F1P&TVa1g(mAG12Diz@Vo>+ADWU^~&cl{)ZDUD0}=gNiRS=Lr zCmTE3evU(`vFulf9Q%HPmy6M-m;**eHf(p!m^I^z`Ps?;s;%89z5T9;!xqP8i$?DY zL3wBPbvA1qB^&qnt17+)$D!AvY$Hx%Q#bHNboVjY7!J^^mvvXkt`(=8Qg~AHp53pS z{r;&*lVm@6hrmPWVf4Y4N?-Pi89-&x2wVAU&_!Vhg}r!3s^8iJ7eUKI)#ioM*vz%&@Qk!#Rjjg7&`zp#&xtj4_jBIVonJtgx_Un0e8UsvDt zLk?)+;Z#JmByEv-e3Ommy(f@p|qlhi}0|opkwrb4~$9(T?U4w zpK-YGo$-emJIKb+T;S)njc>^VKmO*vT72o6FUmDv`24=_grOk?6yY>eTPqE)aap!t zp;!w=`Z*U(_1)VainYYAS^)>xW|zZYY8zgTb_r*Qz1Jm=iN-&W5^w)izZA z0tM`fR)PwV@NrOxL@yWH#5jO?H652|#XF0inK5I=dD2#VV^?caFe@dEU^X1?Z9{&5 z9w~Wm?JvAx|6SaNMTu8zKM8z*w@Q?Ddc%gIT11?fw`tAlSN*<$!qllJ2Tbwlnh$1G zd{-e-qVfrtjW4KrSGhetL^+`fvh`22^@VO?oeD7;Df(o< zE-$YLU{^KFXgHfj?7Yy{T=5N0PvU*}Y|Y9V;cskewc+!&vWm(Z)Jb43wp?NqIK*<(J zIt59nb&C=KF@K{BQWX7-8b%cXoj?uRyhvgaLh_7}(KF^r2x*F)Fn#C-K-vAuU!y1L zU@CvsX=2KmEE&1u#STrS&5L-;NICIYbaGzZ<%gzSZzpZc{-nK4^# z{Qhrc{j zG9PS}i3&8UE$E1Z%r;k-=4z~wwyLrf_02W+;HOQhGH~ue8z%$wDG0SQwu*7!xN<;A zq3Lty{-(IN`1-E4R_lbk+1zKYtFGuzhu=^Hk6gA2G#M>%?I`Ir5PS6(Ytg#k( zx!oJMFnjjGfH@&u^9B*Ehwm=rf)_G|Qi{rv<4Npm$V6T?7uzmrkttIqM{TXZ{b=F|kJ}AFX9(Nldl%Fw=z~{$!CiX z$qKyvT@pq{t?XhHLz|J;PMqw7EVfSXCRQ}A3cgXplxlZEKa**_3 zK7qgI^T8w-z6ylxDJ4K(W1o)?D}CFNOK3h zJHV(LWiUkCwk^6@U}DB7fLJ_BYAR1zIPWC3OIy$y_m!HaHh|p%SbEj^ zhSCfK@l2r}4I+p-UNm`J+$(L{*DlMMv)CVr&$fA>P_O}YnjuH@9)R7+@gr(@DZ@DM zWwu6=6-jI;pA8d-KBTV)DZo3>)YQx`$VLeb2Lz%Wf@;EqiAaCfCz-k~fxjPD;*=J} z9sd}Bo*7A!!(RVD`A%DR>AQb#9Rzl9ARE${Kn;rr8bvM|HI3eW33W6en^%{V@7{|tM#~Q#yjP~oTa0=k{29_0QxhCS5(W)r zk{TKtWa`u@>hs}N3DGb?Mgoe;mM5k& z9Xs=6ainG`TV0xnFicz!;mP8V?QYSsYh=`<+49_Dzmje1-a**POc{ZUdf}5M!5kr7 zfz~*rUr$8JV&vU{g97FPp(sH_Ml4ACjB7EWga^$dgon)>AsXt=$R3pIeBv~TVVxM^ zgQhV2JD3=kRIfSb`v9CVV}NXM0J@=IJW{G^{R5hZ8r}M`H)|Sde~I&p^fL5Vx&XUF zu5UQ_9%J7>RU9BLWAk6z-r91C$Lq1-b4OT92iUF0$6Ca0P%jBKLx+kmU^GDQ-s<`b zXH1^5s(sg%!i;%~{61TPjWcM>%&Fe!Lto=#cq5c2I>UI`pr7o6ViW^z%8e-CHFb8v zehcZpC_!Cx&LHVg8ZdRF*>FOJcm|vhM7mjlI^a02)D#vgjBD~nl1*X1zp2vJUAFO! zR;OGWtqOl0$^tEdsS87;WMd~&BFJ-wl^t>@yV zEvpx|y!+xS{<6)cgx(fwTG$iY#3 zTp<7Y*S~b_0m?UWx2qqI!HV^weXE7DZm8mWYgWrIesHG(yEEo2l%GHTqMZHN8zmt- zPu%W)DcikM#-=0D8Bz(8)br49O=+dMueBZazB`NM6qsx<;Ra@&^nr_d7P{$Jw=X1% z7S5GdUU*La{P>@wr?*q;>TAS-R*^Y!lw?gq5}kr65<--XNMb4?Z8%_Jg7nX1S_7yqm&Q3$s9&M5Xdt5O^$(H&0D_9)Vlh` z*P7P7eipzkMvfo|m}Iv^ypVWA%7m|s<4e+E z&HiT2PaHy9!*+=a*~AW8%s5PO6ByC)jL?~3&K%GhQ;VwrAI<@k5(g3^C-gOor+kyF zd-@UCx%zea`ZsQu?K`*2o!_`sPMtMH%+TsWWGJm8Z9W}HaAAf`t{t|&r2l5pz!^RBEN|PJDdZUz;mC5oSFPHLdn`FZ? zPfE|$B1!6L1aI9+gUBps3Ug>}+J zA~~UhVP?!@ROooKDUcosnC%1In!9S3^sRgQh3d6$o?hG1vJA0w_XAxdTEWR|hB1n9 zU?_6Hc+E?o;dKun>DS1y1%0S!c)31UGkzb6b%!oQk1f3X`s=;<6DMBatK8A)t*_IP z%@IV(#tab!mwI>g;jDf$$M%*eE=kIHn$E8vn!wUwjaCaFQ#AB$4>~h(MztHtpF`vH z5~QTf&QLr|^@+-=`bJCT>BoUMt|#11v|2)@-d3$`*BWWKNGPh{}z4S{`3jr_%5CjpYw+UyIr#*xuMWYUp2$N{! z0N6#FEXW}f2HqNyBG_D=(o<6^+c&LYUF4>lZju|Xzd`2BpO3LQAy$M_RRB}^1UStt z)G(g14EDPQ;59V4`cc#^^4d5%3ecH=V(@om2Nu=j(uu9Qx>`B3ed$YIlD^(Px%rlx zRaQ0%)T0%_fp)H}5AQ30NZxO)TqzeWy+GCLk}I#5GcUVFa>htJ-9Ncou13^{=bw8{e(<9oNzJx(GH&*Kq?SGjbBGz@MYISviZD|n&F2b`OZFt^7*x8||;J}xG26(f~e5h_(f9nrZ;>X)XQzx2J zP|*^hwu6LOJq>QwoE*eAa{%%g)Xz@LRf^Gj7{ha`1^(ACdSEBxh(|b@mL@fw7L`so zREa5`c+4pd)$}1Eg9Q3b{d=~EbOo=iad1Pxn1kz?5Z6JZKxn2*$Ht9$lspyymB-oxZqeYpwg(v$`}gWe zhJK9b1D9WMg-o9@1Jm)4W*C%5m}(aSuCk#U(HMdfhvW-pOs~^K3x>Sn>}rzgy*m_Z z8Q@)A3P6wo^8M&wt*xQy9XoccJn_U6lAoV1w?eDzbUEdYJMMtpDIwy@BZ>E5fN+&LFDkzKoO)oMC*YJ;v}&cCcj;$k{A6ap8wH2ucm+(oNX=Z<*n^bO z3Ccl?9R{2{WDdOeSy?;)(`A^fwBdtMvf6v>SIqO10{w=w zuH5EoEP1fe6?h(39kvM?8XFrUZ@&2!8CMhK9@SF1ElG4oY!l_Eo?Je+1erZsM+y#eZMpzabzNFw}ReYarSmeQ(di;ZeJ_^{@+JXj!tC=#}yzDR6r3G(gor^4KIN$ z>0rRieFU@ASZr>IEo|J}W^b;Z-FoY`kzBGwVP5=NX|4V{NFSAp3a ztb1{HFu#Bq3p+s$b_jPl6&W&HB37$8loaw|ioj(F;raJA*3|Xv+4fjVQ2vC2IWx9D z>cX?n8Urxyj!}#Q!-WHU6)8K}eyi53StAV%4Z5e*aJhqMJ)^OOE#-AJkK~QaJ*~fT z*B4Tzo#O8^$J?lHrIRruC_tj)3=YYU6@jIY<4i8m+SMV`PnwCe@EWd1<$(o3X+oww zrF-b8rT}lhkFjp(M2lJ>Yz<;}YXUWUw03+x$Co&rXR{)}BJ6gZyEg1FG} zh_K61%*&(y6qrP1bIzknX-dX{xQ1id~!K-4*}X zcl_jKH_Fr*bL7Q;J}EVoqKfegTfBMoq9Yz-5KeT76nP-9APYPZ|vw%cx# zWJD>r{`%`xB!{P;ep(PzUj5E;jIs_cWAJwaSVJy|2V(g3S6`MZpur|ByW$$T;HsM> zeas}xw1vcvaBUj2r4a~sntc#3(%*s_bd@W+J%ukVN z=Sup?m&&1bi@zstq1p^*Iw7J zBaU(;&SVb82i?%-c3b_Zi?gL}S7%k#L$J;LKNO_Y(b3rE;aJp#{k)HT8r~eh0J;(; zn!E`$sz=)%wl_5U;$>gm{nCFWyd?hLhFja*i#Ar2HnF<~CegBBL>5 z74NX?HoTZJWYltJe?PV8%7(WOh7WLtM&x#o1}y^xszpPX8Ir2&@xx|hP#B|qhtFy4 z*t-iMh+H?I=ZF+yR8%yKoe{v_Fgpvx_te!e=#R+W7{xd+%sH?>oEh3Q63KR8c|hu` z9>}S$TIx&8zS*9acTs$PzLu1h0pODo@M$(PVm6wSLSB=vr&C-V&C(3*WM@;IV#N=> z|9x48XbAJ>FAzI2tto;W3IJ&KAVGx(cBft40LO@FUAnhI{`bj$!l_D+D{Js_>e4St z*5n0}FnY3>64S+@!BH-E6+mNeRHo^c!#WV$FOZJ}q*BvMpvvua*IlPR-+1GVGIQok zfWFN#A9lqA#iaKuk5{L?nPGBJUS2N0`OWX-&wqYgo%ijZKO!>`lh_iUE^b7M;P_vI zW)&EnXW|$g@N$jJlj4Ea_t`g!lUE#&IeoCq!EZY+PducPNdJfRoVh4mHtr4a1~2knb}jB#K%b3pa|kRer! zk^)(QNhiLa!;(TAjIMb6arc~=bFS;I*iqz2OE+t&c@fz2n{2pK9rUVOK1Mf4c?jhR z6s06HOsXjRh-FE%{$c|mR#p`iOO?9=jBlMUT8qT+0eM#1C-96~CxLEE~ znY8rFl7eh(30X*6n?6F~5>g~&jYC>oMp-~uEG$7LxiI%CXE;@W62=D&DD>eXKGc${kO=dcT5c1+=Xm%OJhAG#@4+TckP8m7s zVr5UvYY)DzZY6C&2sagvQu6ciPpIn9hR!bzE8OCBM46Hk%Rg~+hh)hOPM zM(Jy=kyY!~$f|dLrs`;{rspQfW!K)SLb)ZUB+G>H6A+g-1KBf zzyAGiQnzUpB)deirp^zg=8l6Mvd!ur=rc1bTDZOT1@XBatns-nvzFJ~5zc zFeSDyf#d~UeAC~tQ9gJ$*cW-~UU}Wa~eGQd&B&3W$T26$3AqZ8P-eYxZ z)a(LMgN2spn1KWAAe?TgARxIA4z{|gih|E)ef8B>Jz#hbrrbvW@Y1Udr{iFIf;u<^ z=LqEV)D;T)`D*{sUU3w_1QRwyWzhQDw6?Mhr7agLe^MrL`bm zfh~Z<5~ljvYV+d{ZZxgkR%X02hj1Wi!7`b1D%Ss%(_4~(3~jV6J-DwiG_H)mKpG4h)s8_cL(|J+ zn2l}y`t@?^si&$W6>q)umYj3WISTYDV2t}DOeGMd`2x);HgDb{_x}1`dG`6|WbtW* za^a2NlrfV}l8D72UKKF`GLf8wh8Hezi0n?yEuHOJhNcYS>Ic~>h+6k z+4&O_v&V(J%1im!>39{x$UTPs@#|K0@$lnd0vsE_Kr6uj06+jqL_t*a0H8=;U%zZv zzn*|MVui4yV1c=mOy&*^p16!%mJzk#^?P79mO}l&u`xR4lp=GfGh~eqokDWJW$LXd z6IV;;9RRyv;ylR36Jk1xV7D9#ZPM6V8I2wvV-(}SiN}E=-2{m;iK55USW?0;0{6?j zn;y2*thfaBO4o*co^yl#kRu7UuvNVg$)2(_bk5=%!;TaP9gNWtn+l481hF8i7XfX^ z5{D^r9oSNq`XJ{bunUD3o0tF$@eO}~xCC(u$Z;2dCiacX&XP4PBJCaR3h+`+DuIcu zK?dOM=|SXSkPZfoUk}~#clK8VvZtJKiqJISi(mYroO|xM^5Tmx%B7cHsyn+O1eg_3 zB?yw6o15kFCmxrdEdPlr@Y}!my-bJsf-OEnoE|?wt`DFyED12fNKLWH$dowP3Ma_! zI;V7F5*LLHVVK0{+;sGtD~ z-?2FI&6;T$w62$=d-_j{cwH$pePei~P1Eg;ZQGgHwlT4jnb@{%+s;lVwr$(a#MVR; z>tvqyJ3sfIeRX%$-Ceb+RxQegB|{gX4|38=8*j+?0*Hi>KvTv7e&R(O_3#O}DRR+- zIS86BNsHl=@E=0-GXn)#+hGJO3#fumyd#$*DxTg$R?_k@|u^hf?*PQs}P_>g)UrHD{- z@vV{y9N4AkC6a$YbAXg8m2#_npVv;Aq{xWi-W}2TxLeF%J#^koUp1IcmlefQX ziRsCtr--bLty0Ii_}{{}8C(N3QO_zt%YKRgCP++eSkQcnL#tib*?>_fQ@S3qZdsix*-bUtis#@1j87|S+Nwd00vRK-r@=4Cf?-H%d@k7`SHegF?#w4W>;xn zG5#kiWB;weK{1SqG~Lz5O}D(?ZlCYvtsTA(GFtT)uwzqGNsaD>*CF{@_?Yi!rF0)b zm29q5lDef527in8wqJlcMM1cKOIIa@#@(Cw&^aa;2u5-51+_P!^cng>(1i-fONi*#EG*%1{&f(1@C5tFMKl76gjR!tTo z0yE;RNjDU=7HOHv_aR9(<+^*uIw=N5MxL&du z2JyXfLgrqQ4`7_`=HV#6kxXPQ;pc(ISk$MZDXRrTN@Uip0>=jbcHpe}C9jtDeUp>(Y#X*HZU1u6`O8XD)?Z=!`oP;OOcL4&Par1nEXY2l0-R zdYkka$lb9oH?^G~R(Q9uvzgLh`C{HJC$fqb0~#~a6JSN)M?hYcVhIpPqm9Qsjb`&w z6GN{^sO(bkhsc5Dhz1m@;5_VCzni{9qifb61HLbWamjkbVDn3m)^srxH@G9`g)xNR zs|bv*Qw1eCdYXxjB$2C*Z7Z4msVaLS7^IDvE7cW904K*8$@=D_O?g%{xXg^0?T)_+ zm1%F~t=Edob(537SRTPZTbr_TdwBHca6-~e!**goL&66;jDiU6_`c!dbS=VyY(%rt zLE3?&A(fwoTYikUMnS8F1_azn4ZmIQ8Wga{yErw+)qXZ1sfqG;UJI0ZC}eHbw(Stp zWUu$gd5ny`dIWLGYS`a6FFBzetK?2BQp!C%+Oej5ev}$d5<8!LTEP z5)EF4RnJ_Bb<=gVXvQa~;~uyXuG5#(bai(-whtp^rY2R_mZ?JIpm!#uel(uK!k?kL z_e+xL$kS}Fes`dlt0IXiQE*bTv12PT6QId~$952boj@xS_G=s=;-wu9AUg(ZV=+Ls zlBScg9HyeD9!@;}6m|B96lua-yH5^ZP17w&0#+^wDt=aY;dF*7mq+f3VN)2FoiBYHsLqpTa_XxqBrlzW0w%d8A z1-Kg;A&K5tA>zQL+FDB=+SE8f)a=P;>Lz7bp;7Y$;=3IX0-9E=j<1MZNC=~N=)@!e zGt8=NiGJ~aXUPrq^pPE2cpx>M?nHQ1w(j_|KfDf2?$m+Ao%UxUN+}a`oA|EW^{d0E zes2A?IHoiz)FabWzbvk7-ws!;(TMyw=V7BMbQR_|Ft$DG6DZ`&=zjEFvv|}*bi@~D z5`NA2ay^0Hk>kQyXh^0cV*|C~&LN8#=nT11b2tJi`IlQ1bSOiq4AR zsG1J>(Zr^O@V|Z+TB;=Vi_rSllB~ER77??jVr03dZiij6$~84HkwHVDAb^HohwY^a z4^kn3$AXtY0Y-&K@W&*t_-~OYC400jw`}cuh6jv4=X!Vq}>~{x*;?{+9p}?X>BGd4@z?kBH%(WzYkoa#d z$8z9=aUH?`9Gi_9Z7eP{Cf+f7;=~vpj(?E9Ft@c)Geu0`0%vLf5FBGfYcz$=7N46h z%D0K0KrrjKPg%oS38XD+bd(gyA2{g3=OQu71?+iRW9$n>gMEg8f&T#41J_B$1Hqnv z1X+#-VGTjR8t3N4od0RHr9<%tq@+Lh#X9K&Yz4fiaBt6Wu$ka#6rhF?m;z!SQ&sml zU<)Sv<9R+NMkS!rMklu1Ws&zeNWWx+D0quh-zDAqU@GA!(#dECQ#Sm+&(WI+3OPa2pske^>$9lD*RE-K!$^)TBtcOZi(N|m?uNQNxt4fQ zp|(hZawa`QF(P~evFxZelQbv1t=o39T|#?wBuZ)3;XvNziY0{O~clG);$AQ3fnJlqh-FG-ff!t^R8_y?MI!4>wR?OL}Z_jr{sisKS$$op_ZBsv< zP>KRn+|XB4ua#NlY#5Vlo)Z3~4Qg@cEHah~@?sENKfKDKV2Q{!L+rY%w=v_+3u6%Q ze`}6#ApUoju{==drLuVJhj!ELT?8O4GNPn8wGjCjDB|y>(8R072EGa-r5wXpBYN40 z?zDNc9UjIhkWO2cDeo*2>PfQ4FC=Gm?#lA}+A{ z>sO>Eyrd?XqLdmnt$0y+fvv^#5JgR~t#PG;tHS^LzIsudgvPl2SGO`V&xT_W4;wp> z7Rzzyps8quj8O4=q&(R|$QV9LiAG`3YL#v03;Rw8(HEB-=)Srf>or!ySo>q;pHN+(Hz^>gwvthqe_yG_#wKNQP*j)GSC4W)%Vg zO7YKpo&~_l>;%QdOyopa9ES9Vi5{Iw;KErC3RsvADn@2i4e4Ze1N@DF~~3vX?&4YHbP6nvNr>7AJ5ao9mzWk-8SgF$$XdD49$sf81i^dEO& z@#+0oY>hCXu4z#Co_CUpMXMzLcW7Zd{+Vr$tA`5RFOlI>$8&F(R>5neF~V)a~F42 z*XXlmy>YmOJUPt^hFI9sxX>yFkZkf((%@#m!(yX9A)pg)koFiUV|MVF!~b5tbk$Wh z2wdv(JD2QJ(quD2ih(3|++;c);=Y6q48C^M1y8*@L#t*nq;|EXJ8$cBjwr6C5lwuF zJd?qegoOC-FVUy~5^Q72Kj=HWxh*C{Qif0iT4OBLEuz#80> zxCqo86=a0-f6NwK*;7*Ns#!PbbWn272!3jNI5;E>@{lDnhf(xX^UI$xhTYyGmyOnd zD#t%twrcO^{@@?Eoj4Jq!-Exv2ufXlbEcl*{!5gq-R^vPqwY$_$##p4&P1iJ2xNv$ zCK^|^)QJJrJ-cDSKu2d&e_-S*(PRbKL8I#GXe%OlQCCpz!-saUagm-lgJ=^xr{HIe zjP3@Z=@Jp>TWT-wG(~#TS(F zXrmmkA07%i4k4#xVL7;OJ(ytZDVF(e(irN~^?l&)>B=mKhcNUoemrCtohEFQ%+yv73DFI_GEjiFs;au!{aR>(9Y%weOMF{u#Hp|stCQ0GT%b8}BD8yoo-bD|HPwb(5jhTQt4D;&oyJE4HP93muG5qe91W&M#HcR9 zI7#8%+0*fS`7ZdbckzI8S&-39-^)^ppJ|sfp6#p(l*WPn|F+m855jI_x7PDnADPXc zp{!yOP@`STZn$+lNQf`T%j1eanf>?dCmLjDokJrpm}^XJzxE`Zcu^7hjU^-=*Q^?@ zEF31?jMQOq7vdzfpTu!r1>7BB>|@<(1OT%Tldrk>tiiGUP3u$!=8)>xt5L(UZm2JZd^O zo92oJpCLU14=o(v2lDiT?AtOSEh$U6u#<-lnp`W0JBqB9G+(^19~BaS@tM&sP!cIa zVi7767@1N15gIiX#a%(oZHTDnji{@|Uyi5lZ0yc|ne=JY{D9-1NuQ{N2utqTE`l<& z;K!nv&cLG$An~?N`@Wsj1)TO=R`ta_pj@AQZ%tl&@&DOnuFF;cn}N-VO$|xwD0{~2 zoCEoG`6yfja>G%9A_Z3V+*)?G&YS6c5^codR`eue)Qxc;KslPkEtH^(E`_~=CB~Ha zpRMyi)q6VCQt~KF6{=E_+?os_s)xvmi8rGORQAfTtf!E%tFCtlPub0}wa<8VK;Ui1 z0D2P>IQnwX?ir&KXR5g21{n`wAT`vf*0Y8Q$;|{y5J@v&MfU#5V$rH&cB*LMKZmj$03B&XADL;sI9G*FRVv1W9j#4 z*|lT3D8)KZ2CC9g%})-hv|NC^2QsGmqa0wz^EsPD*+2V~#pf@8np}WoKm({Dm;cnh?W=ZY~B}FQt-W-+4K&(Lh=Gc%Je5ULv2PsxDYq zmJB!tYUaEp`N__9FbS9A^_w=_Y>^IWy&h({>7^)ad69U#eRao6tB>G@9hn1l97*c& z^Brf8_cCVX9tDlg7Q6J4mn`F8h2>&=X?M@^%^VDJRW(w^x^=Qlj@KDs-E6iyP@lJl z)32YokF$Sqzb?HMS&jav*m`3Ba^_xOFS8O*a0$0JPBeu3sy)g{Atu@mk_Zm7v?Fr} zas)aOhv?fdTgbPUqf#y=ucSe7Dov~Pb`#o-M#0}qLkKQZRm98;_>GTOc(6wjQm?zT0{=gQEujGoVok zfFhBHsRKvf?eX+jo9preYYR!|S@7{G$hW7hG1|5LURuNCWVtG9GMigP$Nexxqwq^7 z<#yewrVPNR>O{QyZncPyeyr;2jKYZ4O@X3T#r9L(@3vjr>*f^pB9?$tsp&2$ZY%yP z;HI@hgomps>&r;yWsSo!?w!w%^TKyIb+V+&cUg%is3(!Z;yt!UKU=%+$S_u?QNWhv>=`AxNpgru2&Q@JI;bRfTN@^^tPp z&@D1*p4dD5uNMss>NQ^vp0+0WoV+CTWqj}x`Oq4l+TnN__Y`sIG_oqy+X-5qT@V{5>Tz8jeoTYA_vZv{*3y`dx2( z$&<1T>cV)mRMhX1@>UI2FB%g=J1xx*`DWv!pE9LGpQX;2)=`s3Im2&X0guP4m8;eM z9WsYocyrErPP6Q&BcQ|{{6V&?77w-)yi=G$7{ma`c6{qD>&vMP=3zN0Y%SmxvvgVB z)TUz(OH`XlKaCmS$`AFz&~tXwTi%4nJDtOS2QzE-+8Y2SS>PC`%i`zr)|;R3FO*@T zx~@Pc{>4H-RW5s%it({iMF)Wl58)!pj;5;TQg=3EMXF$2;34uPwU(mg{Uf<4c+gaH zM5MP78w$Z$Zrl6L2B)4#Iiz1xh1oY-@x*Pd-Xyx;skC`{Y0@@Hk^FaIn>_`}EF1Xd zPxhvfZ4!XNmNq-$NDPJG5A*;T<6d3+t#rlNJ^JYc(V`Hd;5#cD+sayp>HmACV?Ylq zx{s!^^4=dd>=?hKe-VVgv`c+Nkfjo@5mL zi9aT47ghIpuX}kd_R5Xl3L2486+xq>QSr1?)~T|>uZ5j*!9n0T`Gv({Rf&n)_JfcX zo>#S(yObr}V5t%^9rAa&Us#~6Ov;8;gj{6e!mBGh{Kc!-bz{OWFWHWZ`YXkSp4!bR zngnQ1JRNn> zhYY-WCuP#4gb?)Yl4Xs~)rFpAo-o);XQG@){b0B8$dxYI0dKiHX!{-K6spY>Bf61< z(m^aao6WTI!1gDjsl;C;_zb4h(@_x79K_Gs09C2t9`;mtrZd^=#lw}>yQY2FZe0l!n97= zcae%9?c4>5W>qbFo*YM}JD`}D*y!&zCzH$dCdZHG;|al!8>9>_2U4R3S|8oiPowB{ zO{7*zF>H<~gld`!;P;!o%1PC(ISiTu zg>{G&peyYM7(VRs>>S$j5qZ&&V%y z+eV4~!v70MK?Ncq+BEnvyuNS8nk~FiJR_dZof~)YmE6JLfB2=W$_H+8uj&Grl1M~D zpFqSeRr!IsR)qtUFbS9ts76Uf#`~cNdm&FrJMvKNFK9{{Epk~LxA(U-6c=q0kO;Ws zH9a5gosU~ypiEVT-81};*@ji>eM0EFes_wvC9a$)rf31vpdN4E!Ma>R* z-EMi};D4;3Zv24~A_#lG`x4JY0kH1;_D|7IMU?~P;$WMLsKl&jv|P}jp&bv_#lodL z`u0SAU3i0=glK3mS@GA4vGZDFY;rPr!?r`Nj5`{iTUotYyUf|sWmC6HcAy=PmvWYp zcm>d)Hve#$^wYLO4HAKnipckG!rR?;l*x;Y!uN&TcZl5Cp^LyQHa@u3`qWzV(ZObB zC7#K&5{jo%<9BcO>s_AMDwf6Ld8c!)B5^3`1~AaLC#i1JQC)pDNjt>WxH6p%*XFNe z^*0s{jt2$9mVeB4<_E&wbx*1k#u8EgHWg9gHeJMk+-L5RTXauGdft1`yZ?KjLs8pM z@FU-d)ubrunakOGpbPWqyYTD8f5FpEDZ2lUAVY0anH?h{Rh>(L;Ng5{tWFxuk>7}n z)eU@02y<|k7m>cha}LthjxthV2CGqOe5%$w?o2@;7Sn>Td0eCBvaN@ROs_h#NY|_J1M2S9GaDO;F^VCYG7i*)Wv#HuYb_UINkz@ zJAZW8Z0h5GEUf;^knH);cl-$n7cmUM>{-An=SD8{t@-Pk`Y{EKPvWVB2s-#l`;Tf_ zCP52&fOe2|odo`?(^rq7NIpAQre9NJL(E2ERVS^BaPjcVr9hgkt;1>)qKtRC*?5*f z*by-_k9xPS@n=3yBPP`B?M||ITr9oZmEE(FPJQ2Bs1;bh|G>2kKm_~ss~5Qng-Pn1 z@v5^^Dl#f+5Js9I;9H;VfLID7rOwOGl6C--)G4Ejhhz+H5&TB2B?afUcLQiI0gtod z;hX)TIfx?P4^k@AoMg%c>6fo~1RSglhvtj(Xqy^frc328#RHu~8?3zqYGn%0=|~Jr zC*GroZ31+%+H5z={U&S?;{pcyduEKzdc^rFC+%z-VER27m3JceNkN_=OA3<`T8O@S zFv643No1n_{c0B1McKn6Lz8977bI|HZkGrUQ%?n9vRjXS(UTn<23`U3yeRc`=g8nCC&D6{T?}pmO zWZjLT4@LtL?f2zhh!huRnb)A1V1~Dr<=WJjykw)9qS*=PP~j#EM|tUT((ZLgtla}< zhiArD`JzadnqBR{^5S+aYgt+30@J9azA*+%VKF$CZh*F=qN9xF>)jwLt`Wt7ctJ(j zI!zQWryIpbd9TFq-);TK)~c`9^R1=?(18u5hWMv1Uo_0Mmza-0-)6qmVZXgEGS^=r zF)0ZGD29rLma?0e!Jyawo>DF$%M-7{g^`1?pxMNho0Ub25%1g2NgId>emIiXJhq(U zRm8-|+vsuM0+F)Bj(@`Kp%crqyt~CSOZ+kq<%|DuItE@_;SbUK$FLMj41q}CcNE7O z%%m@({_`7(CRkKtt;~Y@px~^JIQZDFBC-i9?kUXHSr{3U8NNGNZs(JDI$wvn-!6|j zx1(fnR4HLjGu&A6vt+6Q%L6fQ@%qY1AIg!|LBVTK_u);B3o)EyNA!YYt9Oj4tc>Y2 z^t|_|g3(Ntz!I68rXX)D#%VB7!?zKUEXs&jP^znSGhpTC4b)95KkRiPvG>sLWCtj4 zbV?`w4^l;r{Lbl;gv(m7EqNWoZ|OZ4Gv#0=%OhsQLL+xsUiW_vgFM473!)f2@k=E2 z7wo32{nX}r+K9J!N3C&#@$v#}%$eeP$ZFvg;*;Y)?BE_<5#C}u*2jy7oWdGbEe*bLcxWLGUJMZPjRk`OM7qI&Se6{FyKp5MH?R=e&0(?2t zq|-g6q`g4f@CRrWO>YGf(8cBSz7&tOyABDVq3`dso)T%b_hD?bhvw{8*?y4)@hdgL zgJ6nRE}uX=&SEx_uyQAE1=Dw<(KZ*K^}!4z3pO+~^xbMX3%xRGlOb2P+ut)(D>+io zZPI&#(Gk5=aLD2(tT~*ou*$^3Fy)+)-*%HY8)klm1RlVD}eBHYImCVD%oHlbZkjOj{@M&;&o)*hEWca!{es>3=^-FDx{pm z_tW_EkI!u$R$iJUk(cUW+irka5mKkG78zP0Y+Z1b{*nDLv~QG`avK6V#lXlo5nh3R z!<22>6D2*l)q=SL*!_OJq-DObm?TfMQ1Q95 zP~=mRo48oX9$jrTNQi+^Yk+UP#Im(WL4i3FtNf!}aDL`(oDecPzgP|@K`Ys~r@VYT zGbLr|s^hBroYU{)ZNuS(;_p<)9A}ih>@FgdYd7=0$+6<;((J2-a+X>)RLMrT_{D?!O;`KcjajMlX8~~EJhD*sBb4l0cF)ZTZ#&N zWion?$>?c_!Sl*gpbc;7ty~yp_4SovdnikRq2`spm~H#ErdCI-8?pL9e$E=*pkuA< zOw-y&NRxP7&i?QD#irH=SzYS8@P;q#Z9|eUkk+eZlL1NsVffJNEl~%_dSMvO`BQ<^ zld9o^Tr>uCgg9OQehG~U|YSO+C&V@UK6Vc&O%cJ4(tUMg(n`{)Tbt}NxorHZG zwBqT@CX>s^Fg>pa5X6TTLoX0KG^;n(S019_u;U_{k;|4X&kDdrR$0=9VoCslMLKp_ z^h@c~&qn1ER+jlXA{Xp<(VVl)>UsaMp1)tS$_?1h(s$zU`shHeOXq$WLpXb2G3wGq zPe1I*Fv1r4IUZ%0Ng0zkb}&l zgo}ZgFO`w`YQj#ut$TdjG4wdSeflWj8B{klz#htB$ro0I_-GVXx(e!=M*+ z>2f4GzftjS@`n2r!4Q*4L?fHb97ey4>!>#No>tcd>|_^IpMNN|b<63Pk7f=dJgj(xB}w2#n#%p~$S8(Cb6KKf?A30{z6I0#X)$ zH@K%i5>I)9hH5DRJOuo8b~b3(oJGp*{R8MTNtINjRjZh7NEF>)*Ywx0HvyH=edgEACUtOz+7MDBk*SVsbS|%T z@9qAT9yx3d&);{g0hHB?@oO{BaCp~}6zp0f4RS(?(B+Pb<z}v!zD<%2!IN21i$`gwNZoYV;#ILt(osL zSW@bcC%wGbvHQNOnlDrs`{P#%on-| zge@uC_=1>+y0U&3=p`tuu5&ff)&PqXI?m-Qw*Z zSOlo8s0Hpf&Sm+SP*_lEP)tfK^1YP~k~r-S!<69|C03M+pfaHb>!*FqKG1M397=X2 z&N+0ufznTVj}=!{4hsE{40@lYJ1K$)y4Jz52mDtzHmbu4FQtS`&edhaZ~Y5A9%Nh+(a0aIx zAxCuL;vcBuC$%?lhITvw94B_AyF5=^9{vM#q5+i@EX++{h8ZclQ-+4%>pm420_{! zqaZy4LPkzQt<_0_qH2!w4Y zq3j{cG<57)=A}jRc|>9ZcH-;jeuzbRsL5wF+rxD_9=>*SmvWlLI8XWSp)Lix7c+NE zWDrE|x@f9`-q7O)USDjEk^R5wy8XpHMED;D5%*`?^D+a|gn~vd_n)`o!!32HUSQ4s zBXE*`&Cd;la%Y6gkolbr-$C0a5huxaaCGa(wV{Jm>Fcf~=1BWUrcepKk8lzWd#cOc zHkJ%u_M=Hl#hep?&&cyo{|K28*_&E|VY zrmZT5pwe<4gd3(%+z;(5C20Y1N49Z-ik9;Y%xL4 zzjKoE9lN1;Um6pH*gqX2+8vht6Vx1{J)4Cu_C#dYXj&A$)6f(l6Sn~8$I|?>F!ZQkim&5)6qNlQ&(Gy^CMJ_p4I){ zhPKP!P3W9cXbMQeAg^J}{PdKaztq+X`MnHg6?Tar1S*Dc4I)xXA-a+8e4W{AS%&+q;7c5a)7nZrohUDY&y$ic0@g%H;_9xwj+{l0_5mU=zz3WJR`gvz`4 zgJ@BL=>-BLw!*>JEkNesNG)nXU19)BIyNr87`i$jd~6x^{`^KF)>W{AP( zi-+5s$FDOtW5!(}o;e2?&42*7p%Z9%8+tqrYyH$N15d(bxqF^P_RT#U!yVb|(Q2v+ z|HeL)ex7_bt2v27ho!}G6T;d7GM-LXuvjO32FjnaM>UB;9(}$~Tm=}kNgR%rBf~ZS zL4L9zJ{C`Zz6u2~T^}!aK*cDB96_eif+jvFEyJi#ybr~8AiFIidCO8_rW%cvE7n-c z#@*otK}bFGuOBST;9k3~Y@m>3%*;vv?_^5@eNLw!XRPc15?eX!-T;p}6zKior@GKS z1`U!Hxxn{&MQCQ(;M%|1r^bZ_YWHw8Gi+>OxO3l$${ znK1t>N)=4AtSQj<+WK2+*&i=8J87(ST>%e{s3QP`F&<}00vV;%<<){7@RHVHx5j{V z6u=jsS|;S%R-01^-`^b{7TZO@={B>jXR(+}7^S>)pekpiK9e5qpqvM-J_1;$9-aV`e9E4PZh1BVU4_&Uh> zm-Q12ciUbwT~0TT@YczmVHm$0jK7Lo-?$*ugPHS-TppXM=d)oODiZUV;sVji3y(8Arr7h!N2RLH-;^_qz7Z+p#K8hIqYrc-`|;%kzn~(c3+|H{n)e1 zjGry3t-OeZaN8aLSyB(jNFsfTrLUdzs-8u7=vTfwacg8~*Fyz3yEj8>}>7RW|{bJ>Xk7 z8_Y*P%o6> z%dC6ihYhbj?cl>5&H3$TDA+xJ{_mVHMB`bm>FsVWL0WR*Sw(vzPzjBUR+1Bo;Q??a z>=%GJj5S$)zkUD>G*z`BrBYGIyqiJ{o~6fAK^c_hPul7;SZuf#CY;&sbKEzbAIjie zXEcBFf0PA?@qscNppqoS1%Pu=5+;e0+WcOC-5#|+puK^)nXmHVj2LdgAUKRaFr}9r zlgrGq?Y#N%{8ABzRju81Bh$!_gr{e^N!wrd1xIC%EYF4Ds2yF`K%lu52UAWh!J25x8ke?mDG0pnbiH%wK;X;NNQB)tK{I0%CvfVF9)ZF#*Btk7v3CH>4f-}cDP#J}~ih{W)$@z3mGVy02a9i@b zqcU2=K=8_*KRO*V4ly?><{LbB6e7a)iCGP#NCA1GK3ACqTp+>SWCm-Hmz#~3{*;>@ z3ZN_a66tHIh(vIempBjVH7Q6KAsjNhGzEFq7VzlT3g*POW$h${lWjeMJ4vX<#d88C zeg9cTW?>o-vMZ;~2%(Ha7vMxs1{>eo`4=TrmYPki8oK9(s9K+J2| zKSjqu;h}m))s#-BCZdcp({ryW(mHoV-ck;P1NGZcrI#d5mB@k2n5|9e!6<>OPz>o2;G8;9lUh zc}e-2HuX7JW>tGLpSKvL)bJ0CyvhgQ;5w8F0+uxFT!zdgRq`SXm&mw(xytW*E6P?SG z0U``hD#_Ld%S{U3YH4ef1%47r4Fm} zarxZwnBY^@r)g^T&V*?%RC3_a5}IIhFC3CMqL&7lF^EK;$^@N(;e8QQFSIuMTu6|8 zZay1T6aGm!4{ErC;ie6R8|Br11VTd#gJxB%v{}1;BGPzcPh7GY)=VOrkQQcY5G0=^xh7jAYzvp_ZVr7!*IlM=X5D?cxhhRw<6M>leo zLqiX8AByqkP+v$wZj6^7n#qIsPy^<%{CMhxS!B>Cv0qH%Cj&f~c>FC#O#adNZUh;) zi@Mcr7qD=h_69}KzBm#k+=&Z0?jb~WJdeZ`zmgv<#Fns_@ch;1uSpTZ>Cj(90WK2|ydp~`V;6%jtB_Jq3Fc_NEl)i*m3-BswS4lv*N&Kw-V8Rl z?$i1=CIrz%n^ax6wm-mg5@l{S%GJ>GND)l{?JpQkE>3kq{yrj)$Y&ZEHM++lH;+(* zVg2siqL3ff``9HWR(}zu$wjJ08r`nx`BqyNIfo5Rr(slRUGtkgF?2nl~s z+OG_}iguHt4K-yRCW=M=FNco}ES86k15u^^9^0#)nnOMh8WK_Gtf>$XpZRh-Z@BV% zNV9>IL9X#USCMPw=b69Taq-m8!OQYy@*#L`OXg7`}A8)a}PmU zL?khN!v&*;OjjE)#0-+xNUB*>4tjRorX!LTm`Yset#-IqL!ETC=dIOcRr1vHuAmbH zg@nU^rRNsMW)alRG&|5it4hMgRPXdCa0hIle7(~C+kXG&oZ+)|WvnEx-sui0+vi-l zqun$17$}`Y$rBe@saGt>)7@_*tTsSy!a(!}+mUjmrq5l*ZgI&MpIYoaZi)KalS7=i zq=Fe=;q{}nbDg!!6-aN%g5rC7jX|;7g#1R)oa!Q2op5%B3l8fDnrAta-%B;l!kuqc zfl4U=UK3)kuv|q=zS27Vn+Jls_Bvgkr=wM3onn9<7ZPU*saD>ziss|YpR=-~{4Xu? zJ!3FPiNL}Q(GA|s!>QoO!DZI6&y(P%uQbmCKJwGkWg5nEBQq7Wt~K(u6?x^%xJ>;) z&=A~VR@_!;M^e)x)v4Ew9O_0T0w2NLuY@Pf zpqdhKN|9!AFQ*;Ub&RYfiLe<<_BiiX7~6|T{F1W<2eiQ;;=`OXt0ySPF|PsZ zp&i`*&{l;-r-39L$%sGLF4PYpy%utPqbU|YkE*z>Cln=%ix*g8|IPJP$^%u>7uST% z`rSR!d^X=n2W|8ti-5ULu@{M>(1{|3m@Q#hwOIr^ZJgNN0?Hr`Y|F;qU6f=Zmw#Mc z?s3*0yulLwnns@6_w6ZKLExEuW8bxid~g_ote}97e<#X~AHYZ$Xk(Q4b1p zR6M>i^QN*~jYFx>*`vOf)dDtaNMI@*ZU_3Yp9UK@v;Ml6@UcPYKK-$?ee4?{gz+xm zeaT(U75`Xz%vWzP;tg4c5*`)q16b&v4Cf0Mt5jIexahYmdjLFw)g|+MlgKUYR?uf+oVV^~mavo_uVl(c{k8t`P zb*AQZ{#{I4dAG_xEL@m*(0Bz^Z_c3xC(sexY6E+$q?t?gDgfHA926Qkx^^1G5(ioNE^09uloVr>p%;=mtn&|BN z>xTK3*rutT*d-~O!y{BoLVQ3p2<&3aZmr$L3gnCjnQ{k(uavoWqLb2JheqmRW_nD< zVxder+?Sg`nqG~+*dMOp9o%%l)jdc1dkB$kLs_SyrIn?6z0hQ_T$tIO^ndk=S!@W^ zl1Tp^ik6PfmD!2v5x^yDN!M$Z_iM*xOdgoKR&u??ne7ZOh$oys7S;zGN1ewPzSL;ZR70-zvziGnRN6s z>6F6$hX6nbhG))lCg_dvWom!dPvcj!Ry$|fQ&!Vta+kAj52*wc1>%x0&1b~N?-f zO(2Iw+lv?XoFD%=Um-zmI94H6J6`Cd{Z=L7QeOW91}^$UQvrgKE2Ie|BH(*8&NUKl z?VhjzZ((xq7$rPi6Jg%PL{&TpLDmku9)>QC2Cfog51FSRbiDvu{1vFah8E}5dXtP@ zfaSEq+fLBd!Rw5I;9504lm6Pl8Yc&i^DtN5%5hT$h~uvTNKXc6okT7oF!Rs9msl99 z1Wx-Zdne5J62?rj6?BR7J{^TLMithpttcEDctsN#N#sQ<`Vp3!GP2Xf$`D|jcz}jY zHJbki0YU!0IV<0i%^$oVRLXee^*5!zGKNIdL3kxvyLO%Y>)Ls;Y~7dA<2& zvrR7vWbc+;Z$B&2P#jfv`2;wC}(XRuUPmQ@03|HShv!Xj%u zkFhr>U{K(w6hL>DAi!?#PJ_;h^ylsmeDT6P92n)U1^3BClg^j6ZQH==Uo%wV`F8#C z#gW`w9{l?>$$nsl48QCKS^e%iFeuBFCl@V}2?#%oC{O@3^(ne}N4f5?cjW7j-+*g56Y1*=l1Z@A6&b!PC63+ul7CE z)Kp7i7!)!OrR^jU39Z?d5v!`dR260LRuD{#QOJvRD=7;7Fykm_h6e-$Wk|zBA*E@o zw1B>Eh>EOeMF_l~{%x%Q+g6R%YSMv=N-FZNfBlPLJ@p3S^f4voXX6B5_q|hwpVMdT zC9~nx)@i5YIuibHlbg2CDnc~62#iU)_wSO=-hNJckDn>FZl~efgMr%ab+Yo^rvNGU ztGwrp9*UKTS@P`S#j@|~rPB4JQzd203~_eqFLvkzr+xGv+4225a>2}N<;-!@WWcH2 zrAJGpkF3fM7|>rXo^+9X{^gf4YsPfhw_%lxn0Aw_TK}| zK%PI=K%L0$bwlIG5dw?RP-~d+aU#yiHM}_}nze4~LMAF;z2|4}C)Zoc*!_=z|3<&>3`Blu>b*EjV7L z$7+mZP~b$RfZq4cuvg{C@)zz2o;=_b*|>fK4A*YQQgKg!-DpT+1FAQ#PcM>Pg>LCT zYP{V23~{8$$~P7&u)AjUDw%ifwbBY;S6Qul2}DDZQBWygZqAVi%#JU(e6C#i_eUjT z+mDj{?c3tt^@DtI-wXwIA9>_4*}reUJpZ5PsM0aH5W$lX^Y-uFqW(_qJ5mAp;#Kd+$|tUqmH@ktKk=lb?o5?8 z-v2-rKKrz!AIg?zpM75TZrLE;K6I7%wl0_4wI3<4d)bY5$@uBlNg|9ve@w;mWEQKh z6QX6P`go-ozJr<5uaM2#cS!eMePzX~kBSXo_aBRv$cVEiNM5Z~R;1?O`=`X)Cy|(t z_UPJKZkm6Ur0(7=mt1<8Y5C#@{hoq!ws)9nG|6owg8~KxNC5?SCa`P7(nf&u9dv=+vdN{OxaZ7B61hrc`%pj#xP#3k$Y z7HhhjihttPz+!HI5*L=mtj>6K-+j!Y1n{ac zXc-Uj!=MVBP*CqW0j}eiJZ^0uP-so%(w>Qhn2*UsJ!{ay3Q0+^I{>|AH~|8nB*dj4 zBZz?|2pX9n0p~4&YbCeLBb#;?hzs)*7xZ5_E-Zd=iAAYb3p-20D#L`phWzmAfW8W4Vd;TYg2gYsAooA`Z}YCy zRO#NmJ12ZhK5b|G8WcF;DL|HMNli`l25O2n1mSWF90^#LyqLdCTv<}gPpV1^)fpRB zw&H297Vuj*ULxs$S7+fWpZ;?+z{>$iMogM?;GK8h&8~*zBr(KdK#xfw5*YqW*u7^@+Xo+dDDcoj z51NyblhL2O5Lj|~8hV^ovt(f~{&7FtvOoeC51reBJsaeK8?TVIZQ4M0aEY{Q-vNeJ z(5)o9Kpuokq%N(j+g&J?e&|ENAwT_?h5&l4m>#$7*i|*|wBe)Vt7RWbzy2qK-9T3q zgM5HGRA4<+U@ESHM6cQ|CxQyQl1_ zFiB<=#&iH}DrzsbwWROB5kpZe6|ywzGu4Wt|3G(F@vOqa z!eIbbw)fwE-w%5O)8p_@oD3=F{CV@_R4hSXKIKyR=#x)n)6R4)5*ff9L~p1V0WtvY zY5~42_}dJ(Zqn~O*|1@q)ViR0fqaVjg_{ueJRq5wnMZHbpLqrBl~P(O0WaQVnDc9Q zB=g5J(BpzVTG!!azWT)Hf$4_=vpi;^0Uo8LW&q$yyw}QFOq7&_7w2%E1B{ZYFb}*E zgz$$m#wl5OrSjH0pUL&tUk`xWTV~Ih2^Eo$JpTCOg7;$j{PWL!B_$=2k&!V%-RRf> zFTt+2@4(R`GxltL{@ObqlkWXTn_ON-C?*WY8-XfH8G?rFtqe(%(=U`=KQ5P&L;ECW z=eN@Noblo-$da|MJ}8%8b(_q*`bNp|#7b^CJei=ZiAH(|zQS*rhM9cW|j zYJ~A)P{5#oVqVtj>ea5&VvKb`3|*=RgI|$2n26(-howb%(xFX?M8_pbVq8?n1%Uk8 z6OZQLQW`dpEQI$mI8>i)J4TH z18ej}1hh{8jw>sxP%~};5Xl=cwSx4LDLXq`?f)A;l<*>y8MrLNI-}j>_!t2=Apzn9 zu!4)8ic;0Iit>tZ6Zr%HX<*T2On6v^DjiIei~`E4V*=YUgicmORcZqSc9g0xdKo0( zC>sU0KiT`Y%WMC6P-aaYC(l3ooILf+b8=w+0eSz!PeA+YnT4;b%>N``jogtZ>PX=p*Hb7RP=7$0ZVg8U|@W9rGka z8~pc!|CX_1#>#y+{Y~-@VVp#u5i7oXGo-UNcwngUm}MhWIiUKj`al3id}h#)!D1Js>hzV>7RGHfK z9;kvLCB-;`Wu>K(=YlE(FpI4y!g+WHq%^Y%kG!fCgJq7i;Hskt@) zn9+gR2o7+#v;I&F&(pr0X#_+>ZoO`RT{cWoPO}S@!u?@H)^FenJ6M0FVeU z2^a{94i?tPp1f-K6@>%~0N8@%;SfM*(C?B}U%aVqy?pg&k^%{F08%U)%CjiFu8`GW zx-Hue6iY@;2s%>$Ly(vSt%J*MXh7J}!KX@0* z_yA7a0C~*;@R`yx4yrwky24K_v2gjt#PGm>bs`EPvnQaX8!?{(q&R~Mh@}j{xeXp0 z;1S@{H)ZkdvsCk(bSH;Ikjw3Fe)wVMH=n<`Y|@PRvBS@w=JR3=gQ@`P`QbA+r>sU+ z?aP%MxB{a-cuec=k}}{7dGp0ZQjArEs-jE)&b`tG28d?(*Y#pz=7btf1wisffL=GS zGkb##?~r}M1OV;#`Jo1pAdfD3T(#-j58uE5TLsB3o}Pm%baAbi#2qYg%Ykf&Z_o!h z<)Ds-8FUFijiE#P_VUfQ->LFHe2G2;+Z7;U=&PG${T@v^%m5x-XR#pkZ~*TB$vS`j zwf-qnrVPdL3~cOPzd$2gHIhMr6MzCM!XVYtw$GkmRmmZ{2Z52WghW0-ejEx~)vAe| z*b}K`+s<&c7$XT0mQYq^7Ek@ep9a{Ke;$^O3V4x=9g%6{)~#E>90TSAgtCZ@({$ck z(2=VjnYeI@nXCz{53}Ful7jUt7-n{QJv?P3g8~Kxj-&wlq3`LZpC%%?@8AFax5UTC z!_ExSrm)^6dzc@9XGeOOlvWS~V;BY4D2H_R$$S1TvjF}^j~bzRt(CwCppuKh77Wys za&1p90f5muHJ9}LU?UNb^ya1Sk~aWS=gq%X2E%O`2XsxEh?cNCa2}V!GvSZ*Ku)bh z+rWANMl`_ekf_8KlE3~NDLRlUmZ)SFk{*}dEY|p@VxlEI#_|9pgsTe5`fEw60%9pro&OA_Kxc2hPFUNB50HQ3YOaiI_ zq|h%oA;pfgVnmrsl!0R=$-+0klhenXE6*>yQS-K#+FZ;h6wD*FvT6zH-QQD_bXh0wW%dI>nM1JUfN5Y21p z(|60W_gpW90Iav%e50Ix`VjRFIYclayHZ&pD0O0RXpKj!si{E?{5n7iEV-9Jl34}N z%Lrm2Y_+@>JRk&-@BNpbm8TZWm!ZSYl!ssaN=`d(8Ui`AmyKy9l83+*{Lc7oYC$_f zrmo$(`tFBMW4Lm=n)hF^Vg+}NCA{OMY8LUxEw_B!f9Tm=&bef+7vGA_7xG{-hRXn! zX+>4CHa#Bz9q-s`1$c#;O;o&e8FQ(s)9Y*|#c5mRz}6omDWx4IVF0WsN`p2l!1AFI zzocbVV6uqs7Vq1HNh0wqrM@&S>(Q;NEPCQ8`RJ|ZB|Ck)*eSu~5KHo5Ie-(#U584r zsscS{5)+dlb&Z_~&pmADP`T!sYh~#RPf9`N9;oj?;tsqHp*alwN+2EPtbFx4H@f619${_&Qgk z*e$(Uv_+-P5EH>w8!hi*z0VY=MGE1)X8{rrtMp|Z}<8(EtJ%x85TaV zyon_=8l=|Hn*6nu;x8yz$AW)Qcu7`eB!dF~mnoq7;WgJ>bK5Pq+>&zYsi*qj z6#!UO>z)eq;5fI`CA)HKl<^rvQ9v^R*`G?I9g!=hO+#o@yE0HyQMoAr~*PdX&;+%35NlTDkex%F1h5AF4%L) zp6{+<;=9$}uPtgZjz?cU|8}oEKEVzrw&Dmtf(mrFr>IocXO+OaM+CqsCP{c-)QfdP zIvdrtuk^e0CZP9x08~UcLvRo`B-bHGW+?(^cx{H#HbLsYFRM~T*<*iFkFDBEbqTHA z=bp_^PY|Hx8}UO`kA96=2VOM3DT|c*2ztxZOiX=iEC*V0^@T=lvu93MK}o$4A+7__CzGElu*eI{TBMVOvx?VNJ2Ecj0b$m*bS%X8H`ECuG(J>el@P%;6#H% z#SOsR4}S95=Ld=k3Z!{LRKN=9NXp4Wq^t;%5)KyN0Bi`B$3iy9oV}H$L0nOA8~RBY zQH*3zz@We{P=I~VfBWsXH^Y7&C6`Eu4S-&SzQs<+ftulecN~B#CP;h(0GoDmq`0d~ z<<&P{fF9zRlymXpW0Z`Ob6w8vQ{|(9TDCym+ zmsVbZUDfq9M1t03!mU?c75cjJ69d3Z5gDb((1WclD^cZ&5AKp4=gySQV=u=t6lAyn zP6R0g%psExpad57IG+Li-)}RaTM3t7Q2=pXHzK(;X=9&%?^6UubIs0Xw_#7d@$+R~ z^T(<6MWWza-f|Klp5fi4Y{Kq73Y2f(~}^X4#W+n^-8d?y5U zVQ_~#{<(>yRv!p-PlND=Va0c_edT9z^VHFjxqGAhL;cyyPs&HHKP8u3{ZE-N z`&JdX%mpxrz`PK2z$*d1pY*&6DL|-Z696LBBh>dA3YmNL>gBuj)?01wyz|b@Vd{iG z$~syR00-K4?R|&%YG>Z_)Z6|R?K;@q2wY)fU3iy!FiBgJQwp$)2^POZ)K6_b4tRi! z0}^fFfp;=MyuSh80T`6$pfqmQ#U`3ZGPimT>ii0Ka|v z4sz}M`SRZ4C#4eMv#HLbjhM(xNikF)(lLq3EC!&a^j|$I`xhSrI>qn=asB*jAlQVD>=^tCJq-usTOK$?Pzi2wo5VWnH^bAbIcK_T2*gqFLyi!RHB|?Y|5tB(w3`~| z4GNrK6j0JHECbJm@lRau-n}W^1;$0c!oaFVNf2ZY+#TgtGQ6#l5Mdw>NlA956z$mo zYxyfBD%z>JK>|Y3!sBWK>@Jk6fma3v;s8FGsH18J2Pw$QQh#5Bz!cFj@a+pQ#Q|B% zqXF(}gfrg@9Yzy$6Dd{Z^j1km8HEc$4zl*`RQZR_y-zxwHydGB6Cq`zB#!bkKov-H z30MMdu)o)o&U+zaWQA0Vww=bn~3pL{(StSNY)L+`;;P$>beot2N! z^g#X4;q8q-XV6G0GBVOi2{GGC2`Jra<->EufdV&FHMlHISY*RLdaQ9_?cOGRhMg~` zU-^Kn`{Hfc_4x}D;|1eH`49lkVE9)3>iZw1v=sW9NMwE_KNGxWsQoj~JOiV+g9^}4 zwSk~ly(4w?&-tO`nph|XK8;Dl8-+4 z06vg4{Wh&N1ff7yaL>kvp{hz^N)J3^3EmONi*HOqHW({fqzHzPl)MK5HS+N*i{zu% zo|f*DZc?fPHh35ixZkpY#*FZ$)C*9QG~N!$zZZ0(l+&hX?A>wqwF@2#b{;U?Qj17Xw9Xtv`A_&NK*BH?PPnDeuLd1`>`@oUPF%ye5vdQ zRBgaF0yyU`#=Bi8(j_kn~P(5Aan1isekx*>~M?i0w!5#I+ssiK3 zpumYu0roGYzJUGZ7hila0i0RsqT&iW4<$n-RbC9XT3B4O0;LGJ2*b2JTa>E2Km|fk zk>G|KIwJ;lvlLXqmuL|KE5`kDBWD0`G(F{9sWwFb01#wpV4H)x0u5jiL_1!9U=Qva z4{P~cw^_bTFMu^Wq|aFX^}9T#Zl{crx&L@f(s!(VqyLbzMzRPtJM=&mAAt_<0;n{Y z1`QgdNp~TkqZF2qx)xI1?HN$J0Qd!*z(0D8Azz|9G^kKO8tsP?SVI4^<0TLBLn@5o1QJck(d*Gk)A z6CvQln}bA{V3`vO>VLy>nu1Sdh?QC5g`~F<&E=4U9Mn07AG5xF`}%JG`|TDi+26_5 z;N3wI+LK_{+yAstV|Hx(amgjKua{FtPY{6Woe&I`k^wwmTgpwOp>3Ijy6Cyo0A~69q$|@kZOD}88F(^>QG;| zsz+ZD=>;h*Q#N$bLqYl_2E=BU;n##V@cS<)^Ft>XDm;8v)tx{D95eOm-9zHA-@a~@ z^2k7g&=C9`+u$SnK!H!Piy3VY?N{Jk+atUA{PCLl2hOu1N_n-%#etCw3Y>rxP(7=t zM)HGIrMt~A1O@lz3{;I zy;cHlx3yVfR46&6ohlJ>WBH8T6a5}hdrUz{7yP-~5V%~VsHn*3xQa@~k3oUPDF7fv z97upT44}1Jj~+eP*&%vD*TF_$O78(t@g_PxkN8q_fSM9S)X|6XUp9NwYHYp)UpF zAv2b~2_!jS2Z$gb>B`ul*$6n>^j1E8%>aJ&di`iW@c=7h!gy{20I_241CVh7$5o*z zD>DjZFFiN_@c4Z}^XX?z3|u(tI@z@5t1nI;dto1xB?cCcIcP(o?k>Ry zy~Gf7q+tm>w-VqMOYH<>WNb>9rvQug=t1BK4}fp0{-fmNiGPz#?>!|28$RD4A z5&$ea7-*PP0#<=;1hcJMw^ksR=eu<20wbksq-D#N^7`xWB@Dl_RC@?Z?G$~O@3$ww zMm!Vm%lGW6b;;9DKPwZ@8>OmT@WeZE-lbPU_c<0pCO{f2+0#{7QoI&;qOhc&SoiLDadJ1PUv%6sRM8Od&4_Os@tJvU2%{^2#H3O3$+|lNLiKO1U{g1DuFy z&nX1qCIKi77L|WYlxG`vW|qSv0#sf|GyLPE2gy45lF2-neER99563=0r}BeFjXQbM zkKcVdX5utCXUbd@g2DypoCV$MAJTFpzcwT>_}**~Y|}`k&PxctUuZ+@|kehajb;&Ll=&Kofur48RpdIXKFdL4${2wH`22NpR5@IgX=zS&dur3$fg) zmb1YwcwUL62m&zRQx|mGPWY-FCkY8jxXA1LK}M|-DJ-v*l1dme0U&VTX9g9pfZicW z^5mVT9+a+UUJ65~L?uBaNak&RE%7#H7+^(!mH90(vLdHUw&j&5P{#H5vnI{;^&d1U z;)gHa|9;dt6Wg-BHEY&9b=z&XNxy#mfVp+RfL4JP#kF49omDN7ppmxZt$~=s+o1tT zGbFlhvqM@8zeHM}G)mUKa*tHNIzKu#9_}ShlOMnT9v1dB3c%Lg2Nf}r8xy3{yvPb*hXUIZ_aCL4`FYAku-a%6yzZlr(E#ow~z_5|?p6X3d@@^X6SG=UjA!EP8*f zbUbAwCJa#2pa%~~9f{{m0Nkxww^4U1E-tRWE9r#49Ci)7@!c@&GLsn|G zPr*U?{PA0*6#@&j8-1x%MKR?ZTj-NEC)4K0I{jS@|gY6g2oCjO97%NRu(kr0Xot`J9oYW~@bAU@U z)=UX4Cp3*Df?@SM=p+1GL(s<_FnP9o_Wm1Eo)76eXyQ?w2sBWWKDN^bwFiJ0~MSxN0=d?ZRMz@Ez(}KK1(A|xJ#Op{lz?$;QUCO5@C3hUS)%cF?4$owAFm1cI zkte0kY2v|BIW8Y_B2)1~CzujA@((MPueTRe$R-#T!Q-05#UU@`r=1VB9C8X_;`cef2&qFfMPJ`0cpC@Ikh6&exs0$QVLRT6foZm_q1X?bcG>K@i zXWx@fdVlxUEz58mcjYbj`r?vPtZqEUfpVX$IasJBE>^U~jCTYD474o(4t@ph58;?Qu{JU3b^TmQ6N(g zG-l#6^J&5|S*;FC(he26)WlQeL0#Gkib%(f9aXuayiDZ?e(wk`|ixF3&OGs z_+AWicBlL^x6PTk_kQ=>bI&<=@Q^@lBG3dbhMRT0L<+K!l-CQ6>y;Upn#vS}%+P|P zPMc(Mz~sQmIAC;YZ2_QqcIncE;UKVNZ9<(z&CCYi%q)ZnDM+hWnDPL%wHJ+NDt72nse(9x``~wFLgwr@kb#*{VebM~#YB`)uQ*D~` zn^59}Z65eiO+8giK|7Hz-N;J&zB26bHzohzcF9fL0x521#fIb~M{3zYelkyjp$m0g z=d7$O=#PcTz4zX$Tn@kW)>|?c3&yDD3$t0jLYW1v8WY6!<&o z8%E+afVKP6U{wJ*(J}|HB~%-Ha$e7#wh!O`z`uLfu3HZsI^6B$3A22yy7Y0BVWr#N zyh_=enybD)%xS=h2EGGTN&;Pc>qtipYE+4T-0}G-b>;JLQ{Nu)ayIWMU51U8Iq&~f zDlh{P0)7%~5*%|uHTBx_%luLe7sbewsi+kAT@%eVgKKJ14W=pW{6+v+sg|SWEto0J zDbda-s)A~S_KX~WGA^k(1`|{)ISf@Hntr1mFDjv`w>H$9Jk+Q3qqOvZe32=}H6#nI zfZTM`O}%iAX$IzkVwq%e;N0ba>TqEH=diW9Jja6dDriuH5a*)r(PpqBA|s`FBpgnp zrIAaUbXFNy^`x9*J9sK$1te|Uv|*EYt7@#RS~Qc6UHeGzDD=hHSwZ9!fFz)@q<~^4 zpJ*#`wO&$1HFqWlOb#5!0i*79zv7B3B0=cE(Z#FI5P%RMa(`wyrj!X*C?rE4sDQB6 zSti8A$>4$gq@@mcRS$`pN}y8$HG~4_vjRynNp!fp%WBLifAsZ^pd=kiQ1!YMbWzzE zbMY7ZZLRYcy8o5ZN=h7&KXh)@J*I%)30pS=61S}NoqyeZ0dHh0=$oPq06KNXv=I|P2KnQesEgU8@1@f1s=H*}$A5-?7#3fF z)~{b%t3%7*h6L8I){vT-%FD{T7*^WLbI&~|bWHKuYp==p@#BS3cOL1En4niVWk9Az zIx4chGp;dQQc{xK_rQbl^s~>(s9)VI@6V2v9z(BEQ{O%eK&UUO0YQR265$@0gS2Cs zYd|(HCrjPo`{G8TJ}ULWRUFRCgKEm)i~)JtO0s3!N6$%zewRqw0heZ-Is|b(xjgJ{7%7Rh>6Ko`2SI?wAdf4^U0B`WX?#;**_M=%2Oly#h zd~{lM!2E&~1Kk%DqZ8H{q6QZT(5zWg`R(J6%7SSh<6YDG1L_sNF{R6nua%~=4`$(e z<-25=u#rs;SdqXYKfb^Y*hog(p#3uUCI`+f4yfveM=tUeq#pKSp&D#sqbm8~;(WJs zIB%e|X&D3Ii&zu)Doq9h@SdcF`jL4JsaWiAhUJE>HB z)zFE8OJN(QfvSttijTobNexL?#W!~*2hMR0bfG!}KoP8h0q(NODoIo&BuOyB54XU) zMwzG&Q@$>Mo;@3v`*vaRhmJs6H>`!GBZ4wSAb7E&(}$-;WfH9@H#;zX+>5N=_V^X^tkpS5 zK9>{LSrJA_+Hiv&;jm0f z{-9YJKmm{+Z3cI};&xTEq}`jO_m#KHYp=f{`I@PlV?e4dg_pfrBddTcRR{>cxtI;M zlojxO`Q?`duA$XpH!f_;g$;88S_7;j2BeMvJGyEHudn!FrJ53_s>Ik=C&=%feO;p4 z_mE0hVX$-2m3kUHAn{_$*t{uV6s3hO>Z(jf7ufeA6bd)!pd#k@HkNJ&X# zbaRQuRhpS}!5TqUTrAuy*GTu9AI8TK4uDpJ_n|F4q;$U&jH~o;z@q_2mEdtZ>UZ-M zGG1azu~Hr3;z3HAy9?jYodf&dtWG{ zI;BLJ-@LXRm!0~__YAx52mn)<2pj_4WN%@*KVi*6MzeqX+B4RijHH0Y;Zl-g4BZqD zsn${mz+FoWtrJcAfh-f>{HyHVurd&WZ_&s1gfJX9vLoaIM-B!uA?0Nms3y!(D)0;@ zv~Ay!7lOMtEDJcm-yi_JstK$gIM0F3PL|REW^F+{P5(DAbm)bQry}#jB$ET@FbCKQ zuz|y@oIk;ZMW`W|5}{KVftR)RaDdY)rfDGHtFf(IwTe0pr*t^Mv`7sBrmWJIb<37f zF*qSBJzZj&x&xg$cVT?7RC7cRhm@Eit2mOrUtKhJCI?IoG?WAFLqkIu7X6pMw?N#;hJ0SxXqEXCwJpNZnxWW4tN}@9F(`IOd+L1cy#qj$6w3gm_0)h@N!yR zi$UN9@Qd=hAQ>!xbZ^~}OgWHKB7;WVDZhX8FY??o&&ZT1Q&m$~iD!;a&WD**4GI#D zP?AOvp%K&LA6NlES&7y8`H<|nz!%EaNR(iD3F@17kU{spByo$UOGKa?Lj?&Qfch56 zkihbsQ_qmZ%l!HCA+_W{A0~DjItB>zWVB`0t4zoCn8+f#(2}FO;Z*fH1LTs zGhYCpA~^1#E9p^JUnTtp43YPzEtHF|x=AdqXn6es28G$J02bLP%NQs(C7uLXiqCvr zJOkf9rGz((yj(t?HeJee{akW`!yVdgrm76x3%g*?x9xyIQkj+z^d4Lvh@1W|>3ze4 z;%eVpDxmaAVC#nE1|>Vic@@+f$|3CsqUPs$LQ?OTX#?bDmH6dA7W9Kr)|oTDl1CnS zSblZWuVwTde~_#yyR1HtDQT5H1$H6bRPT%F@=Y1vg8{7-mOMd@T3FcJzze6#UKgG( zSf1nEHuW`IaL01F<9GMJfN1MCZ&-r2?e{Z%rlr00pcG+1MdIV|+cT&Jz@K#SuuCj& zJb%A6>+lZ08>%)mXQz1GyWxD8{HvjL2=zVTGM=B*w|{>oX?g4AC#`F~pY9I{ zLJ$N#`T@*scz0a%vQ^zp35Ed3t z>%0J*gq%*8jXJV>gXQhNJY+q8@P+FTq1@@<@-cM50JRF-0{m5By0rv$b2*(#+qB0S(gutzTu`3IHnyvT1cR#K!NJb^}g1NGFTChdbU&qaM(kFm4&&s zMPGl!y8ZCdd9&sYy6usRYN~1uZ2Is8r==jpV?`M$t&0f4Tp^A%m=bPG-_3-%(1=g$ z1V9rk^jVXfD?1CSel~Gq-BM&|JfPBAvsnGswW(i<8Z1{3OK#8)U*Qw=6ScD`{ z4uZlGfZZyJxWOY0#47n3Ksj6|V=&R;{Ncftt(pW6Y+0=e9Us42VIhJNZj3`W!_NS8 zZ`!m;@{W@L6Zn!0o4kVt4U)-|C(Dv0O9Up>gszY=Z7mBHERaf=8Y9@tgE{fBmIZG<4Y(%$&O@(;Isq1p;d>z`IdxB!0uGc2 zD)Y)K6)xk4qi4&kYl+qrR6JT)M)(wbyUSLtRe-;J+s<Gbv&@U&zfM7bVP2`aaM)$3lm7jZ4PNmeDdzkPf}#v|M9#y^O)&-$3h-($ zJm3yd3+6QQM@DMq(d586$^ipIV$Nl66+Ef={T_RDxu$X!(*h1BqC$ch5Wa$xIs@tw zo2OHf)=Hl;SZ#m}YuBxjfX8F&+^%&ns%1x*fJqOA1U-=OR#X+Dk(MkAlyE^Z zO`TeTCzM~Mg3t{hmY2|p+FD!$OB8O0+ut>5*^*S@m#ZIq1&gWR)oS#$vSjfZiNwM& zA3R-YzyW1vffb?5`tz`X^8mo*l>_9UJiJcgUY#K?LKN71l-!(R%b<%d{l0s*ZdLQ= z&9ju2meS>&0%lZO;5mUTiK+u9qPh}a4rFM)?7Q#2ldr%2S~4>;xj0Flf8j-$JY|Xu zfr+zq>(BC-|r^ zs2p`WA1;|SQiX!)I2V7a9gf;XEr7WZHIG!4mXtdKK1-ki5)M$?wrzvq zZmTU0uGB&6xoaq~KWGSP6|ha$9iLDCs=TVS(Auhbbg&)T#Gc;(06+jqL_t)%_7o=V z3)r!G7z!4-5IAc#Bg_ih5T2T0Ob(C(@YkR)tKP}Mt}Ij%sxVE>`+&fl0L|aQNJr?Z~PWUo3F>M#%hA*sDjQNuB*)QGp89yUO75+{KPQz( z)07QaPU(|d&#R@fXE!TMyNcvH(>{w4!rhR||LRW@FXWdz2Vy*@8KT!&`NJ=)>3lBKgqN z3vs#-jq#{>!*55kKU_BfoI?n&vfj??`8g@S!C}q3FW+|rtBSo=H5XC|ZC`RhZ4q(jujKls;=Uog(OKsry!E24%v5j?g zm(CKS&ezK!y}H#KhBvi}n016Q?G=FgxCA5YlY45fzoBhSb#gr8jxu|$JSFvGh5OI}j z+CXJ_fql!Gr4(sx<$V&So%q{6=iRYY*FHJn^4x@VTjHm^<_s&z^f)N#MO*{OXvI4r z&`@a^J4%JQz=)d$E;Lnza7fNJWEDtRR2O+*+{cogv{%0Q>;nnZltD{@3xl+#i~yS( z0U)2B;G(F!N(!l>L7w88&MGx!51n4`(H$!sX**-L&Ym57h~;oP9aDHrNJub(@~0xh zbk(k1yA+@$kUAMLKi((so>cZ^(qep|VucXJs4aNDI- zxU_=5%m|m}J~s$OSLKWZK+1vVqOX+Ql|2!1%|rB@8j4fse70A zwEVQUsex51R6KnHV_j_%?TPI)wr$(C8>g{tJ85jQv29z8?WD2oCinEc-@WG-oV}mf z^USPSvljejF3rrgcv22^R+=3a^HpOM=WkC;wCG^`hoi7-6>{u_nvDr{xZcFV4?3)h z-DeZzg+-NvZ&Dt?rlzLLKt8FJ^z1zH`1jnT4}@6fRQea3o-S*j14<~v1Gq=0$qF`U zX6qP*5$R&bJB6xIpMT2*OA2oPO1 zv}I#r+P&^O`jN1W5MHk5Q#<_?7j)^^u=)Kc$&ORw-T+9Z@q>VI5U0Kqe>iJ$r?M7y zfEl^gqG)*qf=rj`uxFrWUiah;BYlT54=j;VC=xz5kFk0^ zv8yvTeqhz$JHCN}PwCtIxjk+v=&2R51r_3zpwCNPO&lyYb%&kH(Z{b#4O3KD%luMA zjDAzw`Ol#yN=iC~pJlrp{(Je-#=ct>?h*;)K=wUTiX{T)C`(uAvdlthX{MMaV=&{dGO#R(_BHzceB__N; zQ)NJP_EX72EZl6_D6i1~_?+<1j@TPYvJp~Xn9s^e>jRl|2mOMZjQpK$;B^QxSY$Vg zaK+S&wtw0wDkWT!p>G}co%RJ*2ab!flUv!Az`z5KJ7y!O93QYq#>3;v`c;sB_%ZOg z>|??5t3c%5s^nyr%4rVmJ&I!d&Ptsv(fNWx!;njD2*w2?o~7sTLPX4Ji-=E!WRck` zK*S)eipOXKcQKy|{3a`cY!MF5>Gzu?6<1t-L726dg^NU`6#`&eM`KCRsu>UYF96QKVWd|q@+(W*oLn6-Y!`yrYA z`Zm2*nx&*|AFDG_gy6cXMjoqvNCAf9P5!`SSdYlb03)RtNi`;A&#QSkl@#2p7X(z| zk`g~n=~;r8SN-B*85I+M#R=Kw>~$s-5M=>CNgNzEM*jMi+x=Nc_c&zR>6ZG$tQ^=i z#dg92zH&=)Mj$zdP{C?bk0T=yWc@?4x+FKJStm__#!diF$#7e$vdS4JGaGyQUx+&p z(eq|;rJniLQ3O!m&;a1PHbH0a@HZP52zq^4B^wBt{_Wt@ndmFK`S^6roZkZA%I!4u z)Xv(<-amdt&mKL$v{si=giLAmp6IBlkz-Iuh2AKDbS?3^m0_<2lsr$?;4KX6o(`$0 zC5a|&WcMYAUJJV77aPJ_-v%kj%**aFpS^NQ7F}tzo9|R<=G07(oIHeqavR=$Q$i>n zwku|ki&#`DB!?P+ubPmYy9Dr+t5X@&%9@^}kDAWw)Q%-|^R~rfq^f?WE0H%WmUg*k z_80@zf-{wsyg}R*V~aRFG|Xp`ZBfJ?4dPS6!^{dIg?em(V`$57kc_+U*(+r2!iC6n z&)NyN+&`<0d!IpTAN4|F^V zyR4h!t;Dp8dgC*EBnSo(68PMH*7^gmY}5YV?B)b7dP*=7((|{0H#*Y6-bbAJULsxw z>=Gi7(W%`IH@g5XGtbu=_OfxL(mi{EIU=ds-53#bOo|yTN)jK_?ILm2>|5EA+h09S zu^dwUquOw8*fAMeJ((YFAhF?2EDN`1x4R~Exs>Qrvpsj~4dAZ%9YG1gA1~_oYdv14 zAlWlotv>?6D`6=i7)xaz~>dQuAzge1!zov>C_=-Gr)!dJv;Nn^X>ZaPZZY7z&P3km%%N0rk zWe^m~L5SLtaaO%F@W11zVb7Te5SltuGJoFsc-@g!S0^v=EifuCMGq5K#o-c0!oPt? zimThH)l2@_@R?qkivbd3{Ho($)%GwgsORUgFd^F6i+$~)e&|Wpg6vor?B0*<$gYhi zL|nAxP#6*?R*6K1hKX>vkts77Wv8^FIrEN3drb>Mz;&p|6cz+nohNWmQ4Uoj;<4c_ z8+MpL!x9Snt$E4cCsA%H88)=W}MjJK#0UUu9M zAE#jY9RZ)ibFX!Qobokb@G_tb>h?uOYXvLgdeEvFTq&G>cA-Q&?<~jhAbe67{ZxMW z@a`8kQ<)Kx(_U_Phm9eqG*IvTh20K5m_5E>$@YZ>q81*x7 zrNuq9+zp($Qq_TDb)~pzNFO0&fbODyv;}$E=9gxq9*bfu9v2lcAOYM1Tq+q7V{lwp zMmlAl_|P~3B|gVFb4xR`jX-tZ;1ajh>k;h@jM{Hk7vG4}op-wRVzWJIE?PJY_NV&5 znFUwAlAzxReqQ83(9eiv!*k3aBU!}=yIoveqE-jXkdt0$= z+;&%$8yC;(ugM#OzZ9l}?(7h}np^`n)D8jt!eCo>9sM(S>H8DZ!|wUs)}+7iW{0I@ zxydGv{m8-WJ*BFcbB4}BJ1y8f`_yJa%BDpo5jCXTWV=rVeNH#KfzC8iw>(PDh* zgVv}SW%X|ks_!Nbfl2{jM2m-m&{<(ILzu<$>1>wo*+rsIh{c5K*1=2gRotVkWf_&w z^LW}mJ|d_C%McUM_KD+x&KY181yOcOG|d%t$TW?YMY5wDJ$H$}?uMH(z&ky?476H> ztI`a#-@n_(8{6UR89!5AC78|a^=C2SV z;v4yguc@#fD*7tg6M@i93FnChjnyTimvecMA9u$PpfVTyb@H}O`eLCfGG${|Go zbW-(0q+8FQlepS$OoTd2s)j)bhxk#klEq=iU!@Lw@htxZ`DV0*G7!#H=TJs8+;bm% z+!s^kJraXA?iS?()Lk(yNOrPuK@a*KE&dMilY1cx>1PP!SeE;F`1n3q)ABs)Rbc9 z%jE{c%B_<+v-;yE;i;|*uodveszN!g%J~zKCFlvE(y5`Ca4iK@LOC@kMNG5JOoN-rD@Q=`@+pTxyn9L%rM3Rt(Mr>7N%vQ9s08-xM7-1Ys_n#O;8JxOgd-R-@Az+i%!LuvNE(LPbmCVx!HIhQIsl^?~MkHK{3_N8sjS zGT&KL5CI`Ofyo_|$o6Yu{>3U3&W)vP6Vxmr9WXpRjMBshAuC(mjY) z*y?ant7U=n`O0;*#Gd3i^NWDi_S=}Df{~wF#Y?^&V9te!1)U)s#LMy(bXpKJ9%yt0 zWb2)6Dy*RK3h0sMuvcRK4$V|1uE5w2PB@_UL?mF2mWP^-dT==-i1vE^-I^Dd_KW*e z3u+=TWIx_?a=98l3MK15JZ5n(phENQI+)-4F*P2!({?o0wyUW`p$#&R1LLOR=f>rF zr<;84o4A>)WqGmv7f6M0U)j>uuI}%Ee`roTScO2p-eq>0f!}yqR??+|u`mLegO*|n zq9jB)`V0*UL#)K84zB(C(8J{89u!TA-Slv|?NSGJ9iE_I zsB5&i-z8a$nwpv!;W&@+#Sf%b*+^ABr_~;mwhEAXk={N}s5Ynv776Eu_Z>Htz`}K} zIn6Fdu$;{I5k5da4wH5ynSp%es`AhR!2Jkwt~N~tR@%B|i1J~jogBY8@Mw3hKd6?# zQTqil-)ME{dco9Z=Z8?-$-x(o_9|?3S?3Y;Wa}_Q|Ctzbh`XBpa0`$;n#vIE(K4UT z&ItKqMTa;P=*QFqVeZzc2MjAdeKatw&ni^?6f^(@BrBpJZAU5jqKePlP|Fz<6irQC z2?@RTc$jOQAY3V)24X-TeY$oqBKyo~36CL+?L3PGlKr}gLf^%*PK%aBpeHP&veB|rlgkLJF7O8hjwfdZnfk(4PwwKqOaC#;iRwMsbJAPjB##Mi|u=KXen?&qlE;|Kz`GjeF z?Q-~qq$lgb(2*juFm`SSJ7*!7>D{?=Qmc7$Za2C@xoP{YV z@Bxvd|0PWt?{uPiJawQpq!BN62q)D#yjIoy(6i5xA^3<-Jv|wsvzg0P6smM%F_SdqKrO+3P*HqkYv8 zy;|>7-}zQ;8{&fNF_X$@kT$Uh?tv3r!0AK&(IY~fF%=ZT`74{DYSMHsqxNdt7xor7aFeiR6yn3uVD-u`#Y^FJ57? zl%*qXhH~Q(jX%y)ALqNI+a3u0qKZt9M4R%*s_J-1r-H`=!<_P+^8#zPd}q3yPIiqX zE2%Uc6tgp1lncd+j27G15120P)E;K^eQx7&yFPqys)HuQ<<>f=A>e=HV2>6zD8>zq z?1{Omg1|_zsycpE*Bg(@n3@)^z&c=pdaLPW8Sg``4&&oYn~1bolX)U*eyQQP`}AXy{&%=KZ}AJR zVsrV=mFJ#^(K3Flj8Qhrbx@wIC!tP@v|^a*I3@g%RHeV zW0)Ib2`-eB*eQpS#21L*ZCCW!EjKsv$!Tf40x!E@pv&W303H;F<*Po&$=sZcB5J&- zgTo`9PrfIZ_1Z6?Udt{p(kf3j;E>K)=+Qfga^{qN`d+))dTG<03FN$1+;2AHF3Im! zZOY08oXmm^ww^YP?oJ2P@3>hr&QRcY8yNO;v%%3e5Dg1_IiA1`I3QORBNqc%U5~w6@vq^b%!uMVlRyR@} z9DUw|veIdtQit;c7$}@iteRq^(^bSOXl4m2e#s-H{LLgx9ShtIFD-{@)xS3&DlBD~2**GIGIqLX&wdDw3xrpQOgAOrRElv=m5ZT})CdDIRDe?{sIT!?@w8>^c_|O2%dm3`Bz-)JafF0D00ndeteruXHuN9$Br*(@X z;85@m(MBh&!?J$R_ST!avG|GxN|Zd_!#+Z8l0D3ceK1Eu&dE$SoI;yM+qvW``niZ`7s9YI#RFeM{)aMtH1R zS8uoY%#X#$c|Fz-4i8PMG>V5BD;`4hb+)S2zb_HA#b#q=ID|Wzpqx9%yIhU*HgR9= zZ1y`*zVoR&#NlHkB3GTCk0JMU;h?X5I*{0X%O9<3ag`o-rRv8KzGe9GQ+{|A~WQGSM}) zBsy?>IeO{udCI5`)U0&f&!prTptm(1Aj2B?PCgfpK7*qOyoj2fHbnKpzs$x)xCx8N zYBNu54(W#nsCdchmH36IaTXk2h=J~#^>4c%bR-gQdhWGDwLx#fp7mP0`9X>DyQsaC z{B!kwXM(X|&xDUkq*1o$=778+bpu66Qx^)+>;+oIRfLZkOfT_7*PF0H}v+U7oE7!*<2##~r6YDQX z(s90!_7m3K`^$HGb@kGbKN~^f`kNqbsfO~QCL`5Jh-q6SsW({U<&?Xjnh+AAh?KMi z9llesK8;$s{S+#v<2t;9?T3w;mgvtvS(S_p-y}df-nSCwS=Q-o3q>8*H12_tf$g~- zAN3(IjpjS!0WtZ7cZohy;eS!Fk4EHvE+C~~jK*+o_IbT!=Ef#mk0<`NUgBtQnER-; z@%O#Ws70~Z2f9s*O<8QW|ri9>O`^enZ~( zS?uEA2_uz-wQw2u9o&GNZkChcPHNC<_7GO@aPq+ZE%jvLHgw7-K&<;g8{qgC_~)Kq zCD9PcM=p~s%&{Ip&Pg>qpz<^V=_ydm4k}P8f|XJ{UMw5cw=wuA(u8TLj+KsMW=%?lt4s|U=Snh z%f>g)WjFA+_-dN%kiN={RJf=S*6pP#T`GS4^hjHn=h32v2R2s|EJXMLmvYWO!qT__ ztr<-g^M!-&*Mdte9Ql4hU_14!&$}FcI*OOCS71eLw0Z-!2|{p7dFSs*!Ie>{s=R0&O1N?JEzm?Wox5fjvPrP31Mqx2|cqKjO7j=YHLs+ z4BEDNJZ8PJVo#6#q@n!U+-CL(qktbLiqJEI#7F`ZkfrzEr(J<)%ry1JU3cxtpWmA` z-bwpN)U|EFqt|C`(&X~^vl#W;H%p*y?UK<#>C9#Rj-in}%fDFI!!v}kHE6O>o{J|Y z4HKPVY8_K87^-N~H}F*n03ZzRY-0-we0Ia2Wz&;pZ@2v3OpOjAIkI#4;1m2tJqwgw z*%^t$eYV>Hk{vDPRA*vclfPl|+PB}4jNrrPXw>L0#4net@ZS281DzE99)N0rwK+^a z=T*n%J+`nm&}~=;>X#D+41k40Wd_4C1OfYM@Eb9cUncRhkvtjD$nzDyU^Nn4u~g5r z`XHjTGqTdwS=?$e192Pc9F^vSOfX;WYhdE%nDtW5EQ_(F}s#9A5(z_bCntJl9#Jc?f{`6w#bnG{Kue>L4TDnGi z{r#l11uiRCV|ZUV%v|pg)Z8$*N2Rr&>sJrnT`n;?8CgFkwRpA~f)nkmr}JP8n;R^> zza6CGV|ruPVVyak)`dfe@D+a+k)z@3^b!c-bJ{PH-st5Zu9~_$;%P;!;U9PVIscUs z+|1?L_IuYmPT$$=`2Z^E;JrObsNLzX4r4%sPKx*JHyoqslYV)VCjPi5tZncie&`FB_6 z$0$*ZATKZs)Mjn}j4DdqzE;p1*Yy5uZww^PvFp&bakdAptsDS&4MtmR>$wrb|H5XQ zpW2imHK8J?;1feLy=|C}3LO94kD9^n<`MJO5ksErv-AHWm14BnX5Jouta+{IaeX?; z*gch%=pt6r<)p@X(u6bL%3A&h91>9*tnc>c;^WTmRe?v-@GlE9qM<|RHn1fj;((5u zJ8??LY#KrATSO2>y`wNm_7n~Lb!k5@SUS{@cUo09E;rx58czXPd7dJ1{yz?U8iwM! z1)zda7^Z@TImx5bIBeI;kR1f8Vkze<`8gs-zJ65J5>?lb;(@BeO3@TV$^JFf(g*Z4 z33tdueN)R0eKm4y8!TSgjWVVE_^m0rfI#<+C*(0iB=?(YBf-AH)=GJMkL5%cJ%EPi^-;^y<9Thar z@8fo~eV|j>FfGGy5sivVn>yI5>F%S>Ddm2}ecKnjWbEpYKYl;S&1;~$zX+#v;q_dv zlcR)0?boEkK=SV>3aHO_uKcr`J9%$N1CBQ{Z>lOJdYzUClI`lZUpSBD%8Gs+IT)g zoZ{d3tiO8P*|1V^*D+#U#zZYcv51x_W>=H;X*L|a=ANs~C#cgG>f-QlvffhUOCjH9 z*B4;`56cA&sTmNq8`nz6`7Zrni|$@oVl}!L9aaq9N$w-rZJZK zF}mpZBgR?d93AAMA3=_ZSIR?x3Igl^;stnoSVd2fdfcK8!q^?23l?1aQi1R5giB%~ zM6a$QJX1|nfe6|*{YRHPtZVn}VAyLGy-oaiJ1BzoBul~s8y|C8x8}o9%_U+aI;0FX z*A3twN($oef54<_8`|n$rcdFHE*h_L*_OQ=mM(gCmlsyCLVV{ld~|4Vi-f(XcxdGO zSdUsVcBXR0mA*PUDjxL^QZLRNJ<6~Js#>db*#sZfD{JToI6Q7npa?wj;a6aE71hly z#YGqicP0ozj-7KAu#tZQXFp$$cuebsQIdMhx-wC56N$yN%X{VJf+IbrF6&O}rwVD# zkXri5$gQH8Y|1&6C1UPp6aF2ZnYTay0}jvdc>Ha6dZX;6)XPrZ3J15-;bgX;mGAih zjU7$UM{!_)MEeXSLt{|dxu@?2{3lesUfl5aR?!aWV>G5%B-gT@{e^+fmQ zpS?S{baI;(;q0JD2UZBI{Y&>}QKt;f0mokOXW<807IPm@b!?SF%hb>7Du|w?wyv(tJ+5B34Pu**RL?JynMfTVX(fS9tHmUN z?=AdYCcoErcm$s}mWT~&)^K;iiP_)p+WakBYT(~#rQjLjGeZW8^0;4-NN2u|4!@Xx=)ykM5vlZhU2eOTSgDexf#m5kXqP+vf zFOTDJ*sTJF?RGSkmCcAoMoNZ#utx#BHX%oV6TJvy7LNI~lctzsGO8Sg0%c4akLSq6 zrpFy_`cE82xjFC)C2KBb+9t^#{dfRX-DOkP&{vsx75w)!hG~m!^C8tXaUR@56P^if z;I1iqm5*gutJm{#6UhAhyyurWi98Kl5p1I#2VFWCM+i0GXLF^ zY}}YTD`lnAru&yKDggoHG2Q`TJhs?iL4+*SH?^c22+-yDF^c(e*^QdEYQCslDYx7R z^hVx?^XH*{1nWB%H+z>h5t4xBN3&0p`gqjl_|xt0cr}J)!{^lNd^7D=m!o$~PB>v3 z3-#FZ&yBaa(QL8%I^BepwS$mh<(DResCFx|XKR-V?-EkxEBbDSDT8|!KQMpPZA$#D z;0)y9%t%!p;Ys_g`j2Ssf>;EAB5LPYoZXs&x5fUKiF=CQPG9cZOc>!bcyhyh z12MJKs=tN2qhF6M-^qvD%a-`er`-H<5);xtu$V0o3=f-^>30v|5qQMNXZ0wj#8ix& z0t6=xmfH;(&Kl*=95Q8XHa0VU>I`)XIj{Hji%9R5K^KqxPAeggk0fgqF+*n>2=ro; zO$K`kwica!aHlTa5G=TF|IeR4Ai4{^A3doAnNvG5A=3v=Et5d0l(4@eIonFIu(0GW zwnoy>`n;}G_Ca@+#?sEW(XW8#xr*y!{5s>SD@k;F><%Y9`1NebloiG9 zQ~xn3VvYi=2901FzWVwxfdHkg#bL#g4K2%DO@l(^Q`=lQ$-p>HYgkD!Y*^n;Dc&aK zR;Qce-sUWnwFQnD*S}+(W`J5nab}VsIbl5m^7=D*3n@yhi-vd1v#98u@w9I2&&0Pg z8?26!a6gYB4Q@ZHV;$N|oVl`HSRfxE2wgO*RS@))PME3k)onxd%Sz|Zf3Hp+6BsnP z-=pHqh^2tcSw|vN;YWeCkJ&lu>f+g#NvvqKNwm(ct*uS`t*bAKu|hHjdx0#63hf?YMPGmxumM*);>4^~WwQW@qRi zJ_BZk@N{KS&DAWELEe2hQ@oi|;irJGuO@kU=hWoBfWeH;wh<6oBUSD%z0cZY|L1WoG=M+ZILHT_Ac7VWLd(?^>e61B7|CY!lR&%RU+GhHQS+IjSye~&fcET_z-i^F}pt6fD^^%o?% zd=|$yfKl-%oOd^PqUXchs_3fdXmslvEO9Y~|O=yM$#YiDC1Xgr8LF{$+ zFx>R1^v_`|)ab;HU@l{I=VO`-Kwia7Beg*vM6?yKof*vqdgbscTsAKRYa2SbXGXul z(negywe+t3{2onkFJ_c-;H|QsqwD}77s;9;Q}!dUUuyQq;Z-DCp|+c9F!Om3Gd9J) z*V}ufpTEhLGd3e|Ot9zN0QGilyko&PqqoSMeG-W3eno*v{Kc6sam8IridPB@qFaG; zu6QcnX33-8H9e9eHU533ehzzgcW^fMi_tK)QnU7xn+KP|_P^JP@CR^yjLnXWFnLrJ z{$rzGA`Z3h@2Ug^-N(Uaihl<+srQncB++vO{k#rJbdaES<;E!jjI-wZ9b)^F-~F{s zNH;caqP~B7MtaKSO#k^Pj*JexZ8~4B)tFE`_3Vf|4Z=2R;MO`?}PH`dUIvh z$KB)rgk4HXO0$ZAjJG1x3+mlG3Y5kKbsY}ARSJG(Ptvg;ugbo=U1D!^9>uR~Pi>Jx z9cgjX<~9G7S1}yoWak(t-d&2N^q5U)x#|cJ!@v?<1dJ0x48Zm?%&X>-3ld&TEA3QSuIKUMsjP zm#P#3ClayZN+-;!8JbgyFPdvVy?&T^PHdw<=ar1Ua+hRZ0;TIrId1U~k+yS)Z$ zb7myq*o};g?hexoCeCYn6=rPiR(e0xOXM<0n&zyB>2%f9lGouEOv5U`N>1W+|DqoR zG1_pn$xi>CPKXouQ2OM*g1~m#BftC5StvH{jY=lN)aTt*1C5vmM&r;{qMKpm=6hc- z>OP_}a6x|aUIaZWTQf!?BT0;rJzc>)arCrxi+!hT}|e%>C853zOgT-teC=24gnZ zP*MM2I1j8Kzb*I=d`u|;lFhT~<*E6BV0r8O2gDgVvH z(*Mokweg5(OpHs*X3`xOb8uoVU2RzF{=#J$*|%}v)#TWc7?SEivWMlboQL*dSPka` z70(;C;Ck+-c|Wj$Y;x$&KZIXOD;_zxi}*q1<>hBR^agX(w67C z?f_dXf>wsaW8U(2T*3da5a9b!}sA1rR zciBjU{r!6eZMDWEJy+>z;qdB|1ftx3)n@;D(S>z%>_a(fX8rl!O_DYRvNW;} z5{B^&BXZ_?Bj6rvb@i!{o|}}VsL?zbnxt~Mx~=VH1E^{AJW!Y=&a&U5{t(=Bw zL0kR%xF>)M!KOfg)w@Mi#c`m1Cn>-86M9=)%Id0CpeT~wOj;Z$EmYH0e(+YsPbciJ zZb z(O}p(a6gXr{rNhrb=yl;+E+3b4 z{_a61Pv-d(GlEbf5^Q!@{jF~-IF>S*9I827{zrtTPK!G0HlRYl){kSKS49m)CxL%R5R za7#1nHeK%uXj}Q!Yvc_RLyVn!z>DF1ipIxX|o^w39?unhfl}67k8t&fE=!+GRY>jmyj+<69 z^Rx*Bw%2o5n6w1W9R^iO`Q!!_oGD_|Rnjw(p07Q*@4*=`Z#i&snt`)hANo;N#L=1H~N2+6h=X*y%i3h1tLz$6_d5Tha< zqcL3qq=OT}TTT$32zIRpAezJ6CPuJaL!@cYC(zCsWJ5Lz_<)oNQUo{`KVSNFSEITx z4_#xf|HYO=3s)aDIXk3e7B?y`CL!HC8mGjgdG^X$@=XJO@xfr!h!0O}@{Q9WI4_j5 z7ySQH_ZKW8R)G6VljQ=(d@+-h-Y+lE)7b*iGp(K2zBIcC1XrlENpeg*m-;T4zuUky z?1|yvH<|YnWGQz&RM5Nu@EPHg4M;=#l}HSBo=tjnkTUsQ-S!+&GYp*l&_CfsbnGst z6_zRZJT6+aklGecRDI*9-#}p)=SgqEx>@LgoFRB!afckhn){B$vVQxW+Su}J00;lT zU@GkgSso->4rCuqpg|x!wM16MA@%w@e@Zw_v1>}L_A3t32XJae+~nkfNqkHu5q3fJPCk}=a&-ig%gxC7)(ad`u>R1~{4f{Sdl)GNT)GVMqGY31 z=15&_IYgJt`T$(75DD!|T{dj-611`L@pw$HXWSk<39f>95|GLEy>97ut(}0x_EenF z*^%XeErC2@_BozX4BB$w+}}3LKKF*{_{Md_a=B@e(zPHK`E{oQH+CS-F)b;(w3!7g zJ%BCDS2&oJLtIsFaB?do96hv6P}8XQb@wx@8h$cCErswB$|?1PCBQ(&3C6D;2k|B% z637&GV& zj@-=tv0c^$+0OkXv1LoA`>tr;dJd`sX3{Wa!nK3ME2|KWgIg`-@W+1J7z^xR|3Q)@ z0KXukixof{N4YPFYy`IHurv1Gqq^RczVKt;jL`p6QE~c_+*c+U~c=^iWc11()>E{?VcrE+)Ky zwWsNQ|Lx22xTQ(X&Mw}D70c6mBS)N2;06<}FO~r1fPIEaRWwY1L+l%-zwY;XXQ>xI zML-dHDOhlM1mA?n|pDf|Q!h@l*K2`ksFn?IT?zQg#9&AaQ6r+#WJ)8I(xDI-Y zlnwaPrp0^^YvSe!%utD}O^lD@X*yqqW=zlAH)rw|SewIDnR;c*4(JVKo7Xpu5H`3v zX81pZs`?*h`XiD*`0{RT+JGS(_+^FYU>MQg5lS(xKbQAV<^N@ld()6zu^W#iC%IQU zd~IP<_3=d=L;3T^{{ntG8Vt}0PF?gJSia-&JM0P-X9^)%lLZ(;c$`Dk(pda*8yZkL zOi>Eg%M@=T=iPy_x6UlW2*VAS%7+9I4jx9K$nmzYo<&7P{k9u=78F!R>@WkYa7ZNg z%6|g|`fsyWP;m$juh*>u=pE0!c=CyM*>h`^4|(ANGZ^3D>@FUl5n=4&Kz9C^&A7#S z?>%xPqOQO^d;K^MtmbV|u>W|SVdj!BU_ZlgHxX+K2@j>YcE4P2Hm0U!#u21UOvp52F*6D(J`D`v zVImwI9wmcaG!T*j6h zvF=c-#b$koHeGH$zJ0~4q`yRRzSE43n924HXcXQM?ysWa(!MF`AnN`%R08IpUL`~< zfXyxNYtwuq`e2IYuOLfP*cz3Nd)iEKW}|@lWG_%< zk}Pd0&s$zd8iXSD^A(`6%MPe?9sVvNLsS979NRp(By5Gc1sol3pND9nE^tLIP~WC=A;T@Jlz!*<0`CjvwJy)b^*VrP8c}ZdQ7Wngu8_5va44NTRRFJhmXp|Cd8=oBl{-1yuutrk_Xn(f^lBs-2l}DWp_cs7N2#UmUoNK~~0r?r|4& z5g@aQ^%ijl05Q9(C4>h8k>{P@&VvYvx>gU{>T8Gj_qJ926zv2nfakc5(M8s3X= z&k`c+**4pZJmLo^ci+T-y>_LI;2;>Dj=_u{q@Yg!jGyvv^nctIChl1aL}U+#gn9Y& z%v>Zz%f&y<@_7P!S3U1`YmMe{50@L7@{XJuajiXxN(0uRA+1I0jIwSfGR=emnAO#U zZ=D?JG>!Q?Wsp*E?p!82CBt{m_0N-#T1i-LbK(xJ7oj-8qB0d-4JPI_YK2h+E~}?5 z?@=sI8@YI_d_dvuGx}lbVXDD3i@^*?URKg-VGM)Z;_l%db z#qR#6PWtwdmP-P{}fReW56VEZyS@}kCiOTbd)qi{(mVy0m6O> z&uB@@#Gdo{u%Orqbg{S2SIiTDWyI%l5CYi_OQ*Dk52kW}7eOEfS0MW_V3Vi;t^~1b zhET}W6^`$XNZ6+p^@N`K(`Khb9%MWJ+kpBIg5;(d3L-WALj)S?5C2(ngs7j0Pq;po z=ls0O?#AdgKC#9C8b8its$o-~yD|<0?ZCbPt_pehQ4UZ;_dapbny6F%eh15if?sU* zOB$Pdzsbn>*3DfzpwTR&K+~BG%kN(E9dvCQ9qREDmkTH^P{CF~XGzLXM{w|w;`A@9 zl!A!4Ja~MNY58Lu*iOxX5x>(2|m4vW%q?velGIjF3;|Kz+YuZQd zrdVe}L^(aUAQcBe{0u}hVW4}UH~4IH>dNhrCGRpV6IKMxLI{C1!AmGmU;3||b>$^v z2(}sX|Bd*Yyb%!530|X-=nTbe&tv;;02N{fj^D$a7d$_6d{Gx)L%97ZSzVAHu z0CX)?jhG`1EduJz9)z+lMY|(x2eJNz_F!-&56#`Ph3?ZRB_uSgTwEjBY@`@{BDDzB zkylwD$^gLVdoSocBVc~U8y7I1REIsYjGWsjNPMz?t2MiH)}@fx=nq~KH{v!9k*2%t z*B6>5+sWVylmU>{a*>1*rzaDh9X+KVS=d)&`b(CV|0?fVnkKYAnG3SnUxG8dLy}MX_S$X zku3h7J{eq&`*tBYp_e)~y3ppxJGeW6x#^B;e3^J$?%WO)9qw07BR)?5nseX;C>ktG z&33i6=4&bJd!sqTDZ|U_ab9cJ-=_^Gm{b~IL9aw~ZzJsmvs`9x6{=!oW)xZ#AxHxv z<$(`-Ghhi(91E!PBMkT+p}PO0H-+=_Asufuj|%8)jDghMOl&7%R9v;019w`7=I9e| z($Rg6G415@5mzcW{Obz@*Bk@^W`De`-!Eh@7D8(e-&@-A%(d;4)<(3p=e1@w5YvF# zmd7<|?8FS@WcQ6;BW)P28N7GL9Ar!#Yw;wx%0q(uOUy(xF-kQa(musUQ?hy1L`l=S zxLRAN*}M>gl=$+e8zv_}bcy>}qDPp-`cbD>1UY&KL>CEwy|92U%!T>JO!W#aTo=+# zH?gT>lCD#@iyt??$D}ow&odlHgmsFnmxR1FrrLS4zz@O|DQTw_9WFwf-~@>BzG!c6 z$Ee_!%jH|U2a;Qq4);_;bfBr3b|A*VdvFM+y2nA5q%v&&RrY=Vs4EM{0mR}PZ4Pq- zTvdI9fE36bVEY9FN={8J4YIwU_*u#fvqT553Hh;S#1QGSUc8EnEZG084iQ}kWR{5@ zsodVxvpyN`_y1w)8`$gMqBYNnoitXX22Eo(w%OP@Nn_i#?WD17Hb$eywrx9e`rSLv z%wO18d+m3Wzc!%dDDkbr9MH{z1op%DFT zEa89`>^_D*XJxw(-^Xp;e`Hm4JsZLBI%iV>8LUIP=6;uA{8#hotZEW4OPk|xQm^9f zKTons!s0~Goe8-|VY??b?Mt;=l~~8DfabmD3Tkq7ZtO9tSv_%vW-BzuzDO+F#;^3cyXeS6HRO=onNd7x7phCm6jW$?lu5;cNT%y9A@; ziI5^PgR>umE%=n1Nm;yR_}Jk!E6t-|iTo_*Sz}hxfQ5*Oujp#YpB0{7dQnCuv1=fS z#^>D2oXw;$;daBVh3t`Z3WwPalp1S+?L2ld)Sg>UOaXO$yQpc|Aje63e5_%THLYJ9 zIZEU2Etr`YUU=xj`<4<8bB(D4dZAyz13UlKc7U_EGZE9^=a~a^c#Aca0C+ekmyT2>4242O>bc zR!hTh!;#2~9P?S@iqj$W5fSLV-2MD|Cetpp`1aE_IdpF~!lYCH*RllJF9$$6*P`|V z9!*=9x@k;N!d=vWtha#k_v(NMXQ3HXLASubaV_u|>#~qM9VZbjW$DPwf^!oamUWp; z2X=AX;?t*3!0$ZpNCfO-5Nzo;`(s%*^xfxrXjan~;5iH`|HtbMAuqglF=37=YM~x0 zc&0oKjbeKDr0uGBgZIBR{Kl?Z!Qv1&8CPR4fB@TVg_g50P1vNLLZ?MpsoAL5dLkg| zhvT0#Lz;&L4M}|+*w0AXA;C^mKu_-^siUZ=Ny4ql5Ig+wnjrN)VqqPdB;Az)mV8Pz z6RqXy0woKeL5O7iYt*83ZxWxzF56;DWc^iw-eW%Q1FcS;=bFiwam4UuwmrothE>9X z8^7y)yY`N`;ag9-JnRLI5t25>;1iow90?JjfxdeFcizrY`w!w%buQ$J zZKMxZbRGqPGTQ^N0`pyk71(54WF_)O4wP8Xxopch|sz27Giq81hTDe{_mIzwGgkOqLjH zzLNhvA=Fv0s z&$*8|daL?^Gfojv#7q#ww@?f_a z(CV=9y3Xrt=EI&cdZg>Tqz{02AHr@32cf!l2v~R{Dj@~!CKPr0+q(ZCYLEtor)lVZ zF&jvV*HEP9#L_MGgN7ymw9K6c^VLFj9_ia7HQ}9Z#vo72Q%H#xrPpXc#vLE{oJQy9 zK%PV8A6w-vTK{$+_~ipCzto~=hw>bPLtE5C$Hx!ot9+Tf#k-S6G*D=sXC< zp;dw1MEGBe95*AB$}2@9u-`w7F1P^YU+2$VUSu!G{h-j{I$RXeNxq4qQTrofwv(}E zsS~5VDAh`12!6tX{vlBCO$F^JcL5+NK>}ZJaQ~6Hq#X)3Qvd1A1$1$~_UqTLH)Dqf zaOm~MLa7qf1el9VjEjvue>6;${Tu7xdz{Ie&-)E=6UD{{t%Qk(J{0fU4P6f8x{o)( ziA#x=Ky$Yq23Q$Q)|1L8lZFn^I=;(|ef^s%(3&foXD9q~@IN<;)4vTeE^5rKo`;R6Oq3^??$ z3Nq&HWhM+vG+@#hFlP*E0ut{}1h8AZ0LORXe020LdzD@%37p5^Pdh4YPR6>;ZaIh| zYJIj0zRBlhZY6wVLh2sb_EvJ{sZGWuS^8$!X?+eGh>so>gTErI18$m7UYiyafUB4@ zKm$_d7KE3yPj?7{H2Ilw?k*;#bXZ^Ecyqetw;Y&=AE%U~0m4#SHvTsy ztunv7>_e6Qcz^qcYlPqJ$uV~t9u3XEDNd^k`>M21&^TZY_XdsbZpG#AZEmeGyFR{6 zmrnde$Jf%)rpF0YrSeTs>CE8OSod&>JY8y5J1&?N>u2+|)EN>6S0YGOfykc*q(We3b06d8EF_1 z4y(GqzHOOLMrY#-6ju1bk3A^sJq~*kZ{5eR{+Ofi-+33U^L-kM`$Ey;ECmj9&;oB;cfitZk;}T9 zxTr1xn|Y$+#ro&&X)-uvQl%o9ANC<%1BVJX)_nnhjO$!8|0I@32EV8#*B%&$X&fqs zv!!M&u{Vnbo~y+jduD!du*qea<1weYCFze?`0to4WQ+~nXQ_C5^l#?Dj_0#K@L5gO z&-Z*uU6}NdjEKGiyGQN)O3*$8ywy8;6WvJef&-UjxjFD(B|y_j!a9O;1fiqohV~?F zX{gryhx7uu#@fP=)!u-jN_g4Qp292@t8!1MzGd&WXa4|5LxAg_@CpVE8*`T%9im}c z+5{O1V!0$P(lAgWt7#%>42dcEck-Q4Q5{*J;1HDpcAB}n!X^+I>{r~CM6Xd zj3H(~5=G)K6N+N+tJXUxPt}I_4t)f;1USm1rtUg_HyX#$lL8wC8m-J*G4Ia5>_r#r zCKSL__9N?5uSA6zgnx&g3@E2hM#D8tsowYcV!R;PT4!P-W1ZiN%}Qsc>s!G(gzx!% z0ory~6n7)xPc$yd>Ec&4p4Xxk)%GaVcdRj@A#8Oj7GFF;Ou^G7l9MqPN;;xSUZVgz#3Y1r$0;Jg4p53%>F@H=2WC0!2(`wU;R z11|9BsHY2O;MM5p)Z4BBak7^ zMen6ro7wt)dhdu&Cad}0IBn35h={wb?MoUW}5(MB24fvBM z)g}Pw?f05}Tz6ivI_Bo5l+UUVV1iU-R5A3JnMN5QsP3Y!?z#$QHJ{OiS!0(npR=i= z^yJJ03BiM~^bi=Kie>J6!0*#5O{X-Mr|8OB-n^jgSXN=cD5$ zJYF9g^AO7n=NnDW?gLKXMVq8kD5Vuh6sqZF_3H75*7ji1%CcB$btu+UDjy9q*Y(Bq zU*75qLFC~YQq%LI@Or+DTe0cVF`q3Vt&a9kalTl}5AKMFK->d||0eJ5Y9gGjzbra1 z8;q?eHtKtD9x+S)u%pJ61@zk26hm8o6?X?gme$Lflcf+fGd7nvsH=>&YRYR&bNZ9uKD zOLT<{FU&BcwyuDhziQyG8pc|aOPa9r(bY+K;dM|ii&1X@o5>m1-7&Tz{`v+^tU}&2RDO=vtvZNsUTYS@(^;kve&{RM?>t=b`U5e)=g=j#0=^npg8n!P8 z2jEFndP-kEnZf`-u1;NX4bRq3*5Dwi7)2BYvHn5QVxKVkIBfRLoOC?gY!BhjIn)rr*7DqgRJ zOXoU6QW-y?=v&35ki-?fYhDXWA{S6khO?xxJ{BeA$gYuXR3w%9ai0+)M^Cc=JGgNN z!h*IHIj;S?M86xc>|WaFujfEKL!B)r@>%5(bSdQ-2zPupW5lo?i^k#l)I$eYHnv@H4IT%rJLpB+ z8B?~zVbDNC&jwfM_Xffj9qx){74cT>nD*^aP%-DloeefJzrEEd@)Tv zC$?8vF?dyVit)WU1~0;O+U3D-TCc?MX!zs+>VS}d8Xc6=4O02lS=nV&52;@IR_v-V z++5@-#O|u=y&n6C42kkG$)95mFk|RM)4Vt#C-ByEApF*t4LUd$84Z}20GB~t3{Q*h z@c;|191fJbB(u1Ag$j831>a@c&vG07qjmAj@En{4`r4^bfZy)C1F@XAP$R}k#RfWV zpK&tLL7J%$q4bGSu{et`htP{`Jupy1Kxb|tHrP$&HorcdpDUoIE0mfDj2#l1ZZEE{ z9RhFEU1*D%@HCS!hGxTZH=fIWVGos+jThmqsvhHSf{c}WCe-f^jrMRuqi8K(FymIZ zI6~uE7%w{;!nlHnms^*Y^-z7xzM?wq)Zee(FbpNg^U!-`XP(}Psy@);KjbXMbvkg_ zuaB)taLtr234Xk0Xm)?3Tyj))>RPQq{Ch2xr4TQhRfH+YPJAA>LgpnUC5c@173fF6 zyqc^Vi1lz6;lY%#JYw90jvE{)K!9*@0&&Z03%?qB5sv?GPz4YW`BZv63nEUH@BZCN z+)0+*@z7+s-XNLIW3&?O&Hwd6xyONw}dys`>qaoyzDK&wfnG@?&u(PIo^#V2GHaH zqz(M|sw>U}pcObSwWOx~PH{esZil%mbyZ48O~Xa8-b+~P8%O^=i6Mwn{B`b8$6{Si z$FwwHC%&H$mt55&r(Z=ne(2kk0cwr3woo0Es7UXQsPCe`5Fqjs^|&GQW?%&bz7;VS zoF~$uhW~ps+ef=^#aDI6+U{7>9KE`opjAMcZp>&{n5o#&B#A2e7f8%}o7qW@@J+0i zOgHz}y=%Pu%>Bt+)=~`?4RlS%1a=pmlN(Gz7n@Ahk@!xZ3#8qSTAnTx_qX7g1#k{p zY|v!FzyH&}4SB7_CaK%pWh2Wnvz4BIE-lWwHV{e=`?P=?>d)u$=6mm%LODqhy9dQV zIq;mt;PCXG3YVcCvmbB=-3>hXDh6ZWi>fs{1WB^r2rIcW{|jqVr_sF;;+Q4x$n);_J}Al z2lbU|-q4o%2cRV=5ugbn6CSVtn61Rk`MX1l}05x#FiADrZYpl*?4) zlViWZqZ8uO_ZUv};I{v;^LHAu9z79o)`HB@jB1#;(cM%-snO0K2#yXHPrevSc6KV4 z_=PJc)E~C@P~oTZ;q>Tg9>$)#5WKrf4u<~YSKSUiPj4RH!DvZwJLIqEI=OB5TnCSJ zXpP2ZSc|yksoGf{N`hadVF<3xH}1w{UA2F^_AZAF_!~lf0SW8Yhx)0CsV-W+i+5RZ$dmc zq>=FGh5Vr#o3qVn?#TZTjs1H+)JHp!WNSgQ$gE974t^ZE|Ku2ih96F387GOvZ#ZE~ zzx!6l2TjiS=MLqQMfr+3f(VRskSwJ`1^_4;7ZkrFNo&wV6UKY-v&N}!+sr8v|v?`14)Y_A@vH_TSZ zikmqeB`N0XD#@T!&~JhKy}oAOyRei&Rms_)SNz(K>hamP(NbDKf@k1jgL(4C;eyXH zl?+4tA;UlrXk`ymoz)7HP4@xUJE!&lvxz0C)vO$kfsaqf#70+X?J?fy^^DkuT2#g9 zS5MR@w3>r=B*XNaZ0#py1N?lc`b;@Z^B;t?F$>YJWbCR+qL5nee73yxH=XUvG*gvc zmo9Lf|GE>-bm$Noa!dstHTLurz1C0XmO2N~7$>kEb#n$T2M-OCloxj68$)!PtYUMa zR0@4ct)}{KTX}5qAHb)0SQ!hb&4@7h_^daZMCf|{`2Hr|{^Z3(!%MT+qN?&uOq*t& zxH)LVQ)VG7L`DR0bc3I<-fX#FDFMm)^ud|^QR)jURAAF$(sH6qd z8y3mRLLt+41{l_MM43!;ImY}=n1kt%lj#^M8ZwXfK(HGW3DHAz__E;dAZ^E>(fWr1*G*P1wFL*8 zA$b#Sz#5iZgM4u_-W)J`R@EvRP5Ys)Xd)XY26>Sf8JT}QWg%ZS8oX2gatT}DUC*w_ z+u9T;(%(Dduaa4k4Levc$~1r7OqpfouiTFeXB8aT6Tq(5c+(OeL_UxO?9hBNvE1q+ z5@Zl3*o;wIcfGN~bNld8Y(EjW8Yqx36Y+1o`kT*dq%;^gzS?m`GM*MW!0*1rAf$JK zU2=;(3A8D+A?xt}ub@KGUT%SX5`ulMhpG07c-+$PjHt8j>y)rz=-N$cI z5#>0kv9ne`ioaF)hwQnA<7=ZXE{H&tgYx?Gl#1ymvkV@I>mY)wWh0T|E5^ubfnU?D zfYWW#Hqfs1_m=S`=EyZ_H@E_Wu{9V0+s8@?^o%@=Jj8&>r5-2`#F(%h5qxbOs|2s| z&N!vCmpP}WPrs%`=vyz0Y6r-rNB~vpJ@W>Nso#hNW}q*1-5sk(Y#NsPkwHgxE&cE$ zvNh6kFc+ybDi}DFv7~7g&hUX82vS_ymn{Oer}BXwsuI*lAfMKS$d^Xp7pWt^Vc%$= z<&K}8UK{(*C$SXi5xD|s*GjQ%vA||#PmcCcfUB8hAYc%GwWTHJ;;%TBU&7ip7jm5G zs`QTcmx9~=Pn@+T`JQ}xPAWkpp1KYX`O_^{CZ(G7e2zUm+akE8sQ59#VI3 zZhiU}3{*rWI-70~ISY~O>aE;3&j$7V;@w4n2G&G_L^~{>(s$;iPoU%FjttF%^JiUy zN%}&$>K?o}LsR#@pYeCIzLH;q#tRleQ-alXiSJh~wE!4_+X8U=|39c=JoM|=Jw~#! zJLsXPYJB1g=tnjbTt)>ZbDyu96aszzPbTqkI+Oz~Tskgzzd`Omf6SpRC}!Vm5}Dp` z1k?n0n@(De4cB}TQPD6&B&vLuDcOY{i~-*fTr$`hJVL^6;?6d4eYxt{TX>; zn1^KQ6bO8o$1(L567YX@llyZzWiYLxR#qZfR-)crb{k=LuxBne%0*jg(KS}L$&$0GGF2M`lrxrg z>wyJYTM$6p84F15iIw_s2Og)&X77|v-Nc?AkhtriDmO4Y+<^cJ~D>nA^MlrKEXAvcAYQV)@;4Sk_r~M*pA@>1XJR zY%L=ffS?8RZj-6c>vYpfmZ;@WC~LSt&OyFFVHXjO=pk=TG*&Ej(33P>m6Ot+n{y}{ znPxBv#pn?c%Dq933CFHy!>vPqF3!;wiNG#qnhETd@k~@kEVJSNnDp(sCi43YBNOic ztToA|P3%tv`MNhyh5!I%!~5CgT#EzLTe1%r|A@q=yF(oCv}G1A{>K17MC1NfF9p$_!lU@ujwu) z%TfJ#W-CpV(|Mu}n=uZ8F&oZ*Xu||pyRDN-6v}t^k`0EkG&SpLu+W!87_;xv&EpnS ztFcFudo?y@Rf~Yn6sy88CsbdEu#2tWDa-mqtX46b*8NaWM01iIB&W z3cnsuQ6(2|t`4zY`g+3eDS3?$-tTmsD6#ZJm666Yb#g*w)BhPNjF(c1b`k~_M%>RT zTA43`4w#$c`)T0(QkN-6OzOPT3LR5f6zLFgvGQ=E0A!X`VHyb>7f4KZK-O`73eP?n}UN{luBE3KaNlstNE>MPd zkkf(tRfLzoQ=9c~wO_)q_j3HB_qoX6VlXqpmfF)FNVn-$eJsW<#|JU&rvu!ixr1E^ zxxw!%wxj%%;;k~Tn%Cbs4r<~X#&f8AthqMBmpR0Y$bFi7A z45K3IMsqXCNYGn`uj||QMA5`sdHCQX?ely9W(a_zuNh5j|`GV{?!;wU(!lUek#;6)m5cWD8JEft8zWzoL z-z}<&(EinivJD7BuF_!uKRV->pVVdyVM3clRg!W_B&g|m_7D+K?N?4!_0p&(51lw= z8MD=Ud=pxobLkEx{Yu@7f$_61a-1#u1Zgi*u8pg2kJ8hpb)D$A=)fZwBMd-`r7}D2 z$kcc3^GB!5VeM~=a0Mi=F)0!T%DJ;WLsHnuLS{CqhsN43%Lz+sl{-oBW8YhZlK0JmJm|5~m(n5pvoe`pW?I7Il= zfX?UMI>(19oet}kEwP6$`9!shIU-8Fh$Hx~xj{Z3YZd~O?7j54*o>Z;0%Avk(2)g0 z5;bM|`ahTrC(+!F!s6oF9NHVq*04z;=Gdf!ltTjv>7lsDh58L!zNr*GoaOIDQJu&8 z3$Ktj9ARzq)#}+hzmc32^A(rr;Pl&Qj z{n-zd^waJ^;dkJF4^}G3O+LQUPCx<4V&iC zCSVF~I5@XOo92X(gjv%PvUG|?a63cy8*JAvx}9tvW&A2_vgXw{hSIoI0LCpqbII`# zO(B2G`AJfEdxe3*-G^io1u)Zo1->R^NTBT_qxCWtgAtoJF6?W+unUj6h2o z$^CDCS0TJznJnHHZajL}(w;l*_oSd*{es?OSEy)}X0m+ag&@X2Zo<3Ds$sZCl!6&s zg;jmFWRNv#7TaVPCADRS3VXVL@P?Y|*KOvNBFt$9yeRp4h*R{>3BCJuPcrP5a~HTae07zA>pioo z>dX45Z>=iQrW*^2$nS2#=;l%ajmy>;P7P3@l;u6Zu0DG09?krq*{;rH^5#~VfF7m6_qP`ttC=z*+qo9?3m-l20ox0&FXXt25LW1m6M{n@ ziga1B+R}fkiWY8%^=0^20GFvi|I!u;Ez=PGRblRh(Jv3W3@=UA3Mnm5`}&IIs&r9` zP;cTJ71$C4({+p-@CkjtC-Y$h+VN3-oz%(yk=_qBQY>6!o8B%Gr`Vd#+K!M?#n`WF z@}wFUYMuoEu(j2Ov2r5d0-5L3V=00{*fXMEFQbl>pS}C0WNDbEIcPJqVmluwlnq#u z?bNY<=2q8fbJj#jq%;q>V8P>8g}t^+bb)Se*{wY9g#w?nQo@a%s{2kH^mSTli1>y% z6?dIDQS>t;JdM}*KGHMWO?Eh-kGP`^Ej2#5+U}*;jo=EqSsa@{+v}7HBuDh*7mfQk3*`(NWOLN3~D|D~}F$_ha3TL`jYTJ9Bd1#b{8f4&8+6 zgRiciQ1JVYT@mp?@+ndU%bc0~R?C@j1KmATTny+aS23RNX4`>R=sMu&2+G+X31_ad z>)%1m)Ff?X#jO0*`dd?LC$$y~*iA7)H|i&n%>sq>fDdqL`2W{54@Tnsl#!Qj-rd{N zCyJ|<(p--7nD_1)T+h)L-dJutK}vBs`PQhY$moa+aHz7||H##a$DMTo+Yn^AP)eA}d(gTf-WfYskOc1+k2V zy)qBe6zxJ#`2ULZRdw3P(ux0-M!9z3r8+j3Ay5ZEgE|rhQ2zS0_#Uu}vnwt1$D6PG z@A*{{maBC1IkQpq$6&)#099mr*V{K_&;y2+X@8fJrp}e=`4n&VHn!yS{!h|#GTZ9_ zDa$fPb`Ztj4a1(sdtK5;+dJ14_sJP-cSZZ|xdtTrq8C)gXzgztmG-rRKh9OW2sP5p zzvnXD(o)k8*cbi%b&_*zF+t32Xh!4M_;gqBl8TPD9TgfpY6u8&Qfn|#0|*;kL{h?w zokNvxGia1F-ThL^GTsuFV(o5BNztVhB?{;U!dvOGHwWDgiQ7SYb@`CpqjCru>nR^E zdP9nNOe&GEDHGPAWRwQEyyI06&PU)~+pFNEe~&J&s(!W;8yd`?9qWDYSR9RZ0^LPAAxb*~qcw?)MO@ zPjCEx!ml9Re}LeGWLbBJG+e!gKLT-|``{?B^VrMaLDF{R~K_(3`ry@`qCryWc2w3FI<)M$dFPU|VP)Wk+& z&_bB;1Elr`#wKjM_DgN%hq{q&ebsxLL&j!I)X2+C@_yj~NcP^v-q7+i?^M`>+-v4K z@wPA<1_nwLKR~Egdw!BcI1Ly*pGm*O@!=F!r7GT3sYTzafj3<8aZ|H`NwGLS(WA^LoSt{mHwqOlDb zI~)1t!8X!2C5OOYH=mbv)e0G|%H8vzjrBB_aG>{#I{5FIGp(`t@X@Q$Ow=jm#nbIR-9(Z4JELiE&#Cto_Xh&Nuk4o#qN8pjRX<|aSN|1SnxZX z$G{)|>~tat&RfJ9A=i@OZ&&rr{~0Ta+4|S^Y2d3aOju|s*`IsMBqxVr$uktM0X#yK zjRs?QrnFT~?qunCRB4&Qv=^k(n_?@jw6uFq`xQQy?2$#5&y{tkpp?!(-~6>BV`*Y< zT_Boqo_(JL8AD0LTht$Mp~kP}GO7!-(aa&_s_?+k zh%X5J-xM|dj8zkXC#P_8naR!)*mN3XPMZu%1ORyg*W~XAxrSIJ0W0Xc$cV`7=X&h* z(UDiOv3no-T6J(>s!@sKe~69+dWX<|h)xupfWpp~#Xa8J!)~(8g-FdB$FOLG> zkNvd-+<>^t&O$%kF>})TR^ePIn{v>?U@(5ao@k(>o2H~< zqDjO=S;kmEGtE#;iyKFk*>o!0wHTe4NTb#c^?5`hl zg?F;@LwN(23;3AfN}hFwM~dJlBtrCWNwIfw-yf(hZ$Jg}YcH%}bF8XA_!(pB37PF3 zkS+ikB3P(`gQTl{XszfksN@ol0=Q{0{P8Eb>33?}fOQxrtO=TT>BE)HtF#gSqB zg<~PakZvSO)@Yr|g1VJ_rQO_oV=+4${0mOlIH*J4&SnofJUTPpPyp_T$`@L+P#+D* zeyF^3Xx~nb4zP1{Oo^dAU1(F2gU+^U*)m-IL<`dtb((Uv+U2g8Am38B5RlIiu*REQ zw97>kOJhVJCk#!ZbY4625NlN7!-25XvFVT{A?FoJCFDBAqj!_G?M=!2b=c~11R=8e zF!Atm=R*PhY?S3&GyHS1PZq&d?K!h%k>Ozvcf?$EyeKZ+y)#Si|FEZ0+8o}sq%tXY zqyOoJ6`x;o4(|#^2wyBjLs*O&ERNr7DGfsl+?o_0K=N3T`StW#=L=he6w+)%QcU9GTsX_ z)mq)Co^uXKUbZ*W`*hXTyTg2!!^h3UOvIVol04Y$#lx|GR3!B#Jc*~a7(c~Lzz9@- znn;AGI%tiKrz!cljO{_{DDU#UUExk75j}O5KAx*63n?%$z*6)qfY@*@_K?=BTjNZ1 zqF{7~DYcT_B|~nl)gjfn;J5EJ!?RSgfKd(LqviiWyEw+ccVqmyeijljz((?-H|*%B zPP?7*uk~h#I;DUWj`Y0pDphSRO#IHNeU_ahuP)pP$p`}nb2WiULr8>AD~-bt&#SdCx=AWb&d4a? zkP_@sqXn@4k~ySL>Le-8B&H^ABJSZmd47D9 zi^xLkYi}=7(;p0j+gz!gY|G5=f&dn)?Fp6Lj3&*+9AiI1{zFxLa+vP&{-eqL(G*~^ zY2jv0$s!dFX6<=SnBf2L>}!OqI^(c;=h^tpsn=3KlUzQN&?gEr%Iq(ohPUb{E0f6c-xct%>`NZG^!;MKom$AvGDYfYL3y-w zB4M~nyswv6jk((-qNFlJ?)h=Wd>j2@D1D5w)S{oiTsMJuSoit+c_4jPZ$QXt@lElPRQBVRE)*sS<9xMs_X69t{TzjYwz9*7FFdz5Si*FTXQou%>aVXh`Y(;xooxah5ch4 zy)LTud0N)FGuyC(7c6O`i)5$R8ik<0_qUK!h^-`~%oB`~^TW)y3byoF(slhZgiIhV zZyv2myH9La$gruhbcsJqfl`aPef5ykvX#bVkS@sb$J2#~YX7RY8Mu1SB^7bGi~eu* zrlu8e4)2PYJ(T)*S6j&7^;pkeByTAi&9tu%D87_YrlGj<%Cj(_YJnnnEFtE%W%!HI3 z#(%y$`IDz&4++ZpZYPA&*RhDo|4Ksa{g~VRH;oG$2Z!om-J?4Fw#j|~!OeAyVEXx* z&z26GB2_8c zmwMWyNPo2WW9Cee0pV2z=>p}3!$d#I&LvZVzltxl=ir;O*X8uj4{~#Y>z|70jNh4MtYn%xjp8>79MmJN3hhUA!tJoe}2pdbzZYM?sUZGQ*d!D zYGr!#K2CRdMH6$m<`5kVx~toKAey1^PUso zZo&IS(gQ}QNk#x50M(E@Hz)u&4W*{eX6Ew-c@5SYOM*;WSgoc-hFnS_2$!s`dBr!aR{gA zNOqJO_Ksh>E%1&*!k^&m*pw&O9*vQ=Ji51=P9u5Asyp6`FjLHE8S*WsI3fFxIi%o( zI(&aV!Sr~!>%_7z3ezsEGW(BNk9KcfHoNl0zei7Vnyic{<)k|K?PG3xK{Q&L5dXaR2=8LbNPm zZ_=zF$+4quuuOz100ue!3S)3|Dj)Ci-c}-b zgH_;I1u;S0RjG!II6$27ltBTWubcJ{lvF6zp4;V2Oo>?_FHdh!*u(B1c}eUguG{H= zi_ttzJ?3cnIpjl8aN7^vs20XBRG@80<5w$C4U%}8QrWyjZRGofh`i)f=}UTpIX{$W zJn6#SZ`Sh*d8q}DYmq_3CV>?-`r?H6PYe6RUE(GPidc+wmOF^j%G=jVLLmq-f_BtT zJ|9XsSzIbe6m;JNsVV@~&)XA!n7g5FXxx2>c!-U)e2eA!_Qwi&C%<*Q=W6BHtNZ$p zf~!)_Kk)lQ8Zqo1{l>>L5#xwcmC0j<8!y!O*~kC`*U8{y!!beIE4V zic9*`0C}zEBj0;|4BxWdpU*C<@Wa0U?DDF>4$2rp>Hu0lEzSYhWpOCOA>W07q*6S^ zZRXImidrp`^B^>Th4}1UF(3jEPU;g{ZxHh;NMvmf&36ylmB|baz|u(ws?utgvu<-s z9n0WQQ*5?Y9dL&Oh0%{B5Wk`Wl!Qm&ZFPOkbY~*q#cU_TrEjp|TaH{(4xR-XpUFwN z;GX~5ca@bzzbiJfg_In5kuoytiba2>y4fnSJVQO16NIo*K}<{o#2~8(+44%zhq|~* zAEI_!2-MUb;d;K9IbM2+b@4%ggzD>@FBoT>A?L(oRkuqMIdf6-t|vlPDGp>AvF`xvvBGAa=kPr z4RM8s`fq{i>L6oHvIO`U&mv+cL{Ui)@F1O-CR+V6^Hhyi}O z)PuUg3X7fOl+u6+J`Pp6yKDa zVdJUW?sF`?#^{p#&PXpJc^L6fS5dWhH~TwZgFjpHzvurPki+v=fP!*U!fy=khj*%F zOyYN2#(7f$D~0L+KJfpG-TV2pK@ZVq89P?D?x)X0o(G`vIW8ps&8V#Iyw+oEtIU~V zgE(~G?Dy@v#iy2JA4Rrpp`epjwc@8N_DNzI*)ZLZGN?Tke>~9MT zyBL%JJGxhz9wdw|Qq*Hf1~WhG0Oe|Yq%|sw5eE(FGo_VYT^Zx+UK<-zLpHb9Ldm-A z_C02ochB8krd7nA-#9rPT>jXzq41xYrEj1{+rJ2pkzVf(o>k=Qr5$s5(|QRQoIOu$ z8Y1gl8Mr_5VuM(y!{D@+WI=*>;wX7Q$#-4#>HTIi`ESj#Pi`Wr9=GT%)Rc%Ni>H6 zN9s`UGkFtB)Pq(t_*5_75qL+bNP6!J*01~s_l8^cwR)qGq}IMnG+o0KxfX_nku8;* z;}Rs(Vz*W(1PfqGqSuy0uaCAR!~m;4m!8B~A@<3OYIL|3V$I* z6ftwg{_W7D0a&8=Q+hMl)Zj6QN8>m#Nh`YNEEST^e6$vy5qe|$eed*T@*cz4d~)Xh z08~M%z6~affR~fVEMP`$J~}4z07$^ofyp8^i$$zu1(Lpgsq9&`Koz&_+i#^u&t5WV z(j@uu#~;Q$QV3oKSWoqSNy;j)0G zWqYzv6J#sJB}KA$@i*w3bP;cG1esd}h$|MYo+yCpU`%M!o}2QcC?__)8owm)1A$T$ zIOn#WbPHTe3+RCNVp?Cnwr&C40)MCl&SrFPy6L9+xWIdpCr{piaKQAsV4>HAh7B9? zeGNtzv(E53CTmHUrvwLJFUii*&C{`bmn`3uCE3MJG1&t#^h<q;pYLMngJl}VsjNs(T)|eY0~4eZoe*zC$Z^FufJt}^4w;zV1kxcMa$)j|H6_#Ct-pMpt2ONedRHM z9H})xtZu;GL+fSlCojs%*GEd$&hMq(+RqSAKA*%ogS6nnJU0!juLgg{@UV=ixq}x@!)%6!HTBO#R z-&bS@EoeiG;RZ>OV6K69!H{dv2s8h|n0pXT*%}gUzWJds6fp;VJ!j_9AwzD%41O@Z zEp>Ng%9y|HLzx+F>B|1s)3uQY4fYZ>2iX*MrXoe9?b}k-I-*)lJojwR@&npo_31@t zCIIaoY@yVK@%l8-jK{%Xw%VmiY&<8f0Sv2BwMU}D`TC}Afxp@UI^g}QEv{crw}5Ve zKgt4zE?v4Ppo;>5w8R6i3r(?}4zCNT{rmSHx^(GM)2vyuTs?a9@Y(Hli`#R?>w*G) z$gF`uYG{c_t#DCmmMw>JWmW2NfIaA6A-bhU15O4z*NY!ToK8Q51sbfNuC~nKloEum zvf6AC>M0aCxL)>r_Npv??iM+^W}dVeJW`br99u(tVQ~P*24C$KE2|o>AYQ=^K6baB2^Qa%FavOC=y-Cek0BT$% zr)0~IYgCzAHg7?Y2?tnSHi!jJBj%P+tDMgUy{ z^t!HY-MV=L0s_G366n&smpTnuHE7Dgd=*BOG6u*R@);&LHB;876^jSVmEGV%Kr-rD zc?wyub72Y%+~FXin{gTskT<{}w-|kjI$&yBtzL&XkEF`>*>B0x=Wmt$E5DHDH$5TU zURfel+Fi}l%k!Juc7R2b#cYmBsA)KU%3(;UTi>u`$r2y#OXd5`AAUqmunLeG5p0*l zD#7An$TZZGb>~Y#0bZ;rb3i0vS+jJ$d^T;oRIgr3KK^)yY}vF)Rl$e*P=Z|zN&i}f z^y9h({sIf=fcGyjvVIBO0=fnM5DWMjUH)zn=z9D0>(?IZFCb;u(7AKx>%REn3z<82 zE`hEO%on8#%DtEov)5JBF+w@M)fKb@B*V*@at6@2l9^W`D>fgIgSjrTSs``6etOH* zcq^Ww-s;%+X;P)(O%D&G$|Wx+ypbBkU_L;I6+`+?$=Jv z|1--=u9^2tcVbMeGe5bml@KN&CR7*zm|UKA1Rx(^-3~x=Xy;}b|NJQFa7ABv__?>l zUagLddiY_1=99ems^vwb~en8ZSx-F&5K)i~`YdnI7rTi&UYX+N$3$deN z(dpq~v^N=Jw73eS;xVwRhf}qrJ#yt=^p$Rbi(vun*Y9FnS-+-k0o?++1uo12d|9fY z(Q-zYK({mY&7U)8&i9vHc3Hpq^XL2K&70@KejgcKm&q%4AjA;)QzK!9Du4^}Vr3#uN<;>#X{8C1T!hEeP`xE*tq$)1hNW!kHc z%eavPqKLHoHkMvs1jt8TJZsDa+(hqg*sz1 zK&%Oqk#cj6%ec|EtMmKcGD4~~Xdw?i{G_Z}w^qKKGe;{|bs&g%U{eIlNJIp-hSdTw zflbo}d(jc_`zoe0HixrRYBldg>Jf;Hh`_ z+Epw1;Fz&a!&Z2bz`ODxynw_J3rbc@V0EJ-?09M!yu>U=j~o#MV3E2#ZWUj6ypr_r zd1lgzX2%Y|7MBTyH;1S|oBCUUA|B;I_<&68DDv4fnxK`?lWu`ZWC86-u0$2mtD;*# zw}5Veatru@F5luxX4E7oMP8Hm}o=o3_WYbN)1gG5^@&;~9s$ z7l>Sr3N8b}V6~MWG-#Et&&bF~jf;!3KJdT;u6_IVq5e?h0W-~r&Nw?39C$&KVxsaxtcyHqakJw%4VFYjJe4}g6DU4NpV;l|0) z5)p{5GiaXDMB{Cv*$2`SYBsb}PvW9s;jQL7OT}?ef8Bs0NZZxP3uidOLJpr zSHi-=2y_)tB?vtCOP{ZJynDR_Ul?>nzGJ6KW#!gP*^%WGi!D%NHKA8jU;w!AeANt=jWyHj zf*UO2`GKy#?qHoTj*HP)_`fyC?jw2f?N<2LErL!JlhYVEOyi~Ss>b_Tdv*KIJ$sFp zxq7+7>jK;_@x1hXJ7vz4SLD$fE|+;=ML9ja+o*S>TKAj95L?sdG6%SQ2D95@4>4uz z+hN)E$xEkJK0oZ8L#w`Mgsj(LS%XCZT>xG_$9$gs)gWl#bDehJz=3O%lamEe;>=sO zZuOZ=;FW(D%S+uRzzPbllNc&+$0{bwygz<;m%Q}wjZ&vsOX=M2CV(7^V)`rqs}5+A zV{12);rBl&ue~}>=FQgvWhkbP)}V_s0HS30`E5`m3PiC3lh!nSDA_;y_w}M2Dm1TD=)Frfs_N>i!MU_5}Jm=!Fp~CU%DSw{iE~cSmeow_;3_=53{J z(@TvGjB03vYQ@~Yu#I-+B(LvWy7VxvVcui7VEAGc1e;htqyO;qn?!&T6WS}4D^U4Ie z=SqC82>_RY2MUqE}A!cealO`U51PVOr#%K zq@G{_|L@wyE!$ti*D8H)d%$H6k1_fnqahpn^Q5&gHPn2T`IKV|?JWoiY=kSh0M!=X ztz0S3KQ~rd^t@Rt)f;jWCEA)T$lTh(_F_;G7e)l)!vZlu5iN=K)UL`7je44J4U-QQ z5`zPw19?F$@!8gsZh?zx0UhvORP*Z>|D6`_Bb}r!UAkauanW{^hp}UE^}hX`{4l2b>J5_~zoGEd$p$#~B9<&Hd_G}^&lS+e_OF2gf?gBCBEQ+VapTFK zeDaAI6WE+(WsnU3^!pdu<-))(?-X~36>d|3nOd=dvV87G^8K>;^2iJ0C9zh0Fth}_ znnjowT?FNMA~>p=+&y|6$`E<#-~Z7f!6|72Es8v_0^)T@%eqx09N>sPjd1{$)oji4 zxNQQGDs_}eLj4xjH$PkDYTo9uz>RB`ecQBE`&*GkG2P`6^mxku+f**|aNl{)h#~9O zt{OVzw);Kxnzc1M5Z;bmwF^nA#Q|j9@ReLG(kfA*0doAp0wD_jPH>(FOfGyuNJ3;No)=sb|23GavAg_^=g;RTEtagb9eFGi9WY*2Pr3yz zx&_Yt#<=L!(kq}_;D56~{rU|GQn&Aj>CvMnr;d*=|B-d;TEPF!j(>7)6FMe-#*QG* zHD$__kmk*s--PXN;Zkhl;K76Mf=)L)J3HGwdh}>dqehJsD5PwGjP9>X7x)H7(EwYV zEzXJJ1rD#Q-<2!NQcp;}2mV13{J}_lBHqqqtpMalWj&``v#M-JFqa$!fwQAMYAflYLckkY=7hil)mMvQ*M=;BttZzl| z%ff#N05d=YPz#bl7R{X_AHO$FuDfNVv~1s79AFN`;DntRlmZq5c41aFN+~CvHEAz* zj2bJS%$P2peDnbeQIZjKHPF%UBDAnU!Vtx)W4&nj3sE# z2CuQ*-CWfhOFN_0Od@@J6J@C31W0S?@ zf*v02!ADK~jbIIjd*X%<>tayDNuef*2_l=1JSyLrtMMEYBCDYnCOdZRInE=425BB8 zD(2F+bqib!3-GDdlWu{(s|B=QWv%vG4;{&95*Zopc;Mc9Y*Rn@VB*|=Gnw`w5`S~i!FPfwEIs3a-#6pNX{XFwkUR0U{g zKYS;9j^G&LEI1)kUwTx&|Lz-Ew|>2}ZQU9Y2&a;p(7vkk0YJ9n$VvHrf4-wJlpH!qF_)DPsvxwL*& z-2%Vc0{pf0zx)?{H1mrlk3Djq@$GlVI};NUTaJD1*=^TffBm&!MZQBmzO|W7gD&l> z{`n_Zzz8PS2+sm6n&3pe?C!beozA3CIT&EKJ!A?pY}hct#57NxI(2+-CB`;V z9v67xud}(#btds;%S5eikqf?c({f~QMls&q774K87`3_>k_EN`*wPktg8u{Ob21vQ zYvWkFt5lBc+$5`(%$ILIov3m(zj~NdZF{xPdGfetHvn&_x5!+UmTJk|uuzVznY1$J zgiJ=p*;oLvnW)eGoXGOD9kl(w>yu>>_~k&)OFyjZVMjB35PR3GS!4X~fB!4fr%zWG zXwsyK3>Ywg9SNyduO1?$RaY+C)IofBz?@qUJR&bIPezP4z1}Hw?(|!SHu10bwyRVE6+H@ZNLJ{RmtzSE|IsXc}vvFdytmeM8;E z2svI@hE7O{STNboiE@dC34N^q(NzC>P#2H8Oae_NW48grec>^&u5nM@-97Jk&h{&M z_8GEx!Q7Rs1V;+!xk6R=AN&Dt943NY-r_UQJ~xkGcj$;GT(ugtv6R5020h(sPdzru zw|-_0WMIdJBNnu`37wc0b?VCIO&b;1t<$!vgtzZ6UNeHEU_^sDUB67h&l6xhJUDk;B@tjb~@kzv~vbC>A)^^LkM#qF+?Ez;CpG zAMiGB(5maE$?s40UDCLw!CB^TJ^#{+mj8?yBi*jJV&t;Li{C6SUuS!NqoIH0H2#(l zuri$nB2%YM4S(Y4C$7vqnmHKzFUJxL4+C^F=7SE^9U6-9QSw9pninQnK<;xSVqGI= zKp|!1m&%sCIdTkBW{h@i@|41BI80VoCG61T4CSwOu$~6Iz^z~`-2ibJhj+`S@8-&^ z_uo?4n_WFzBHQ%#+2d=vgRN#$_K%BZ*J*{TPd;btTxoP_ zg#&-!CMU5u8#HKe!_J*MKiafulNa(3!_lKh4TldOmi1s;ArBEu_&a^cd+)thI&|nD zEn2jY`1m*p2?idF0u*rB#>yQUvb_7{nGU{0f811-lEbP{|Q+Qws1> zN)lkF~l`Q5EKXeFT-V=Y6A`GvUMnLU|tShhWca)SOG$p7lr6~cBoJ1q`2X6w4#294tbJb1 zORprMmw;3$f`}s3y1MFGu(B?Sy<=}Eg8g4bbk&ujh#(566bni(O7A_Cgak-PudkQ? z`{uqI0;r1(3EoNO-8S{ynLFQ{Ide{RwdCdH2@O>&TeeI_jL@;72*SxD4?ir>dLh@} zaD)8qhCAhoK@WiA8zc2&LJ}8mlgxuk$pkpPKJo^UCgG{};z?CHa(n%#w$1F3h11@X zac{gNA5WYt*WGX}^bTvl338p_o`dF~dy&&8i`ExP8TkH~UxYPZXk0}Fe#2aNz%2a1 zI08gb$`9uHXH6bw{pyp^aWk-gx7U z4_|rqp&Rqc1HQMX|6q$tYau=lMMn4r_ztu#$f+BzltvM9&(Y461TXp*L8}RRlv5KU zB-UIi58wJvS-EPpT=e8v2{rGg#2l#Qfjx{LMn7Jv1AT?pUQ8t2m;`o9iIOgjlM#Rd zKg<&$k%u`*PA~fvii^$&9=&8;%0*I2z8Nz@J6|wr9f`6sYSI z&IM|UNc|-!{k6tbTGJHb6H^;H_$9Q@yc+= zNCA#?`T$nLy(GxJ@4ox`#j?2=#nnKJ z*jxbD57thD>aDs?K=$1 z>%)jONDm&5r_(B@<^Ab3*IaWo#2LI053!SDPK$H3U1@2l+SmpizA_h^+&-ExK|M}N zY9iyNeId;=noA0nty5whkn1(e>Rko0DH~cK98j|W$&@2GdW=k#FksD2P|InQ!_Dx@g$7kg3Qilyr44}#A0_U*&GO`3=gWaS zk6ilbf5g=4Oeyoj6gJ;2Li0^A7AJ|+w83or*sPgiH%sqU4J6)-&7*io5eM+^Rai6L zA>%?LHrjw4wxcU7Zx6dWd*$MJ)JQ_n9zH($<>IE{3&Y(bDrvTeAJ-^kn zA9?+g3wrnJ=j(n-tSuF4cj(q_*ywxm(MN5wzx!5Nv}p16Lk~Ulc$nL3>f5)k1@eF# zERBz{qSj$Q9P@Pg9!8@lo_M0({Q2{HuUN5ya-`?LH@xMRTjc!n&zEl9x&@myZHg6A z$O(j5Py}FfKhMooL5}$0Ya#avo6OW3!Wl|MAe&$AmW{gs;!45s!l2CiYHt;uX)ja% z#9{CT+JfEys9lN#$bt-Mb)n?$+9)d_qxRf1V%&lr zktwelZ8J;Z{%qfulgHS;nf8IC*Kf3>Q`gh){r1Z*HiTpGoscuCMGfDqD+g+op*9A* zOUFYGKQjIG*ZzG$^R^v*kG$}XExy4i;&Gv!gLWD(_fV}^*&sF-65d*sx;@aE6AXM2 zt)x3tjqF&vLY}{yi!PXvKK!mkv_3=10d}c@Ap-L4)J)<-92+_rHxhb~59Dzr7X9|@ zjC4tju|qQhIQ|I75-2eVym=nkvqepjFU(0)Iio6nDGKOZ-mcABHd=k}tDng!&6|XJwMjO`lhKPM*NTb?KQ>F5Z@&3v z4&AxEd!POI;>Ak|WRweYdoc@9=e?u-a^)=16+fc7!cT))`02a&mTI#d3C5VYMvWoF`VB z9jIDM>#%ruCrS$dZhAodXopSmc5IM`ZX}~0g3aGAku%OZTl_F(OEqz98r-60L7&Vm za?1QI1rh*vn6jfs5>$yeAciLCi|2U94m(t0c`JkKe)ul%+LLz^;7XegonAYyU+>{> zz4aC(x0U04#U%}2pU{V}ye`WanE%Z;t;bKEJbl8132pjZc(w1kyC1W~rZiCM<`mim z{d6#x< z@O!U*27yMv>)&OZ8qT1=pGyI@T*Da@I9Vv5e_Ti1_~7&RoqPEW-t;(|y;r-262T=q z>;Q)g?bxxyKVia0wijP~f!E(dTfqNeW6vybv@~p`eZ{q}x;6$MISw=4$>LZ~dL7A- zQB&h)&6*W8X3Ur_GiS~`4>!+;?+R~+^)or^tg{rzZP~JA5FnT6Nu{BKTpeiP{%>-? zIB-yb1-U{uyC}*s0o1n z@B}%sjJ}I6zPQ6zUwyTD>C&YUJ$v?q=&>JC1BZiKRbG+@#8uYQFhNjL0|jV!55Nha zhg|UhP|?cm2W9&K@M58lSTn0!yT+ViXx+sG#0=XY660{l#>Jn@3y2Rob^} zD*+lw0GCz+*LYt5z}pX$$%^fzVzS%S`#LgZzDuoiJR{eV;uFxM0iU;bhkxFzkF8&R zJciNod-cEIxyAElzlXlez`EGd3Cr;%S01Y&R$a6T^13%JTD<7JFFyamG2o^lzKgCI zY_r9sD1FFQyc2TM+0AO^bG!^YKH|G1&^3cwu4JD}^5pBO6J*BtH>73fzLIgpT@nDN zH~_;F(8-`jRs9753HZ|hGhPg2ex1^#VUo0}pC~q;8+mj3!7i@7?Qo01D?$H5OthC! zq%|1&>eJEY38RMhL%@ab`ZpP;hBGMe=Tbm*pFg(3`Y0}4*kt1Jc0k*(Tgbd_VSg+d6 z8?~Gj95gP^67cAtxYpx3cdB!62?`DaxU9**fdgBDi%ae;LGD@b&ERD4;KAHE6Z>dGDw(<*hI5LYvJG6_{8BfDQOI<1D8<__ z5$IybC0CcL;+p6#-ZQwl)Gp?#ER|i`H_4J&lc8d4Mo?l~1$tk5y(O)2bMyKo-^$K8 zlS4L3)LdV{IUXsJo6C)jB3O=9UVGgWyY~2+sl%9-$|o}FjEZ9qLnWdK*^7z1^I2xE|cYZ%3u@(+*_{0 zYt8Bqv_jt{&{B>vqbQgkWwjx^$?FR4-Lfk1*@U-j>y|B%hH0srd-ng^i&G|lI9ZFJ zemNOn=}wgQXu>K=4bX)N?X(FKCyko-)r@O)WaY?xPru>ocJ4oHSS|rK8^kx$&YvcJ zKq_cG1Mg2&jSv_W!v!ZJ)(CKQp}`?%+d7%}_A9b^-E!%A$&FIK&%eYUmkJFF)!^)M z(xKiu(#2E<<>t3vdT8IWIbXIxAm{|tiiV@%3<~_|6kv-toI!z;i2{ntg$ngMwOh~mLtYvk z3fU8-MMB8bqivcvfPkoW$^xur!Ur3m%D;2xF4NMbODvy!@`=ouGl#N|3*kS96|1=) ze)!>$;Fn_y*<~DSYK_7*V-IehFi!8^EVF)o6u^bNXCsJublbgqcVC3-4c`IYM$HNY zxHMqUs#PmrLP7%5VBJ+(zj*T*A|7)3P|Z6`j*wL&s!0u^7}6oSzCA50+cR`6t4fenGW?N)hQzh;#tn}#|lik*jzW{cJz5GQn3n4lTM3;_lS5nq#7gkT^TdPH=jO}4LIB*X5$ zMlQbkUvgTv9x?))-U~0h2ouZ?B`GOIX$7!CGloWHG%0}PP1z-~0!Bh?F#AjpO|-4b z2Qa2P{Y;Ok^d4vMiXn?)%`UAN<>zwQZXuCCK{rT`zoX;49C6dV9BSx_ATL zZC@m}kndJcPEY=L9MM?2qQYxbdGP%)-+%wZcduQweE8C3-zS{fy?5YWcRgZi*t)CP z&7P`MkFg)HjqAMxtsDek;pu58!UDRRphwq^?^;=YHYOJ{WYSwNGK!pg*NYO@zL!+m z;-QM#gUJTCz@Qm>j0GzrN>d3YHD-8DcKp~B*D*C(+BK>NunRJ&{z!`JPUVUV?H&!1 za3vrzBF2}$FVlAaRcDUF!&|^4P+~TEEaPZU;LoN&?NCrA-lA|K=;m4rC4>@+}Lmdyl;K8b@s!(QTrWM>4rMMqQuo8t@ z)91r495Q6c`jI0?mf-wI$9|*(L8e8AA*g0dQa6sn4@X5aI7cQdk*Yf3n&mjmU2(+~ zO<~6OG~Db7PYx~tZtP7r-K2E1La!?~_W6^OlgZ6v-I#6-7Z>M>gUd}#zt(A{OF3kc zlc=SlIJy`-DW}T;zPQpOnFlH)`(TAQu}p5UN8v68X6zd0bLxX7tI@(uP&l_h#*`a% zoF)0Pb>k|TF?qCq_r{eW2teATvRK-kdxhAN(yBLpGxZy9W#L5R`Yk-)F&MeSxVeV) zB)yKJ8N<{uSJMX|Up)e*dHtBMSRmeD`cd(Q|4})<8*+%V3Z1fOb0HXxxW+_-%ixL& zjCW|kdy$ApsVK~qhcE30U?uYE)Mb*|w56>7{!4lOft%!?Hw+ZW*-Ct30@T1!iv->^ z`XMJUUHgt z)6?YEhhFrxIjxV?8WnHydaKb72>0!%Jtr6R+6RS`0VYDkYyK$Ry+~uc>eX$w9jP{QLmYl1SyIF6WPkLH5)im1X-zHHv);#nqDdTP6T9jPft&f z7WI>$mdvf>;t7I(%(36HzmdC76@QU-M{wyklg}$??d~$itw(@t}a-t~okRzG=vF*Peg%U{8hL6cG)MN%z(%(jqNJ0VS@UG7!hq zFc9En02|z7&z?Qj&6_tX{iW}`^A1B5!f%9M3BT&b8*kh)bm-8%;C_PD^^=a{6n*V7 zF|f+E){*!Am($ZY@<@QD2GS!FpbYN#@#9;9gG+$h1O9aQHUO(px88ayt(*z0oC!55 zq@|?=ZA1*U%1e1%4Ty5tQ}cNKJ2(~@S&<3=ENaey%OD2u{0gt^%!4^!fGe*z2&-J+ zaFN@K5nJN}bHGMfxQPw-EigqZKBrV2%nfZ>yDT*0{ZWD3{C!r5h&6RP^K5ZfSIXv9 zOTR}>pTd6uzYkt_1cpCJKRr+#JhF|@vuTFY+d$^Jon&W zx$4TR|@*@059ezB^L;YIyljoj$&IBzBrozHP6GWg$fA&kh1Ldw5IIw>1?(D0x zH~w%(VRf)gOmZU`bkC#y&S&&7M<=D2-I&<iEun5P=<)P1&RxbWhoPmHBO420KV(|w(Rn}3D-?U}T z%B9r5%Q~|bKSeh@GMqty<4b{Xw>rL=8o3!1I1UuxS6Uxv<_x}n=(&Bby4mA5M@58O zPC2znth8&9028M8B4f}c$Af@Q2X|pW!1zI$Pc1GkHe<=(Oqs}a>(&W21j(jNo5*Cz zh2IUoE$nx}#Owa<-Mi;QZC5Go9XAL4o$(OMXtZF#g4W2iGdw{qxwlQvIp-X~^0vUb znY3=*TADR$7D!4;3IYG%u^Q1xFL2Zd8niL$_XW62J?xM?MKaZ9GpeHkun9npvD1rdE^m_>?n0* zzx4f*P~@<4L(_^~WwJh}N}?&zK(LD(ERJYd4PC}>Jbk+ie(WXbec27-hs->o6_hVS zoX9H6=Y1(7hu$Fii7> z;yZNfDgFO`wZCJxUJ{jD-|9iRL$GdVMd=9osUnP6k#g0fI}<1PgiH#+Jg#8&xi~*x zHmwIId&+yVZ|8QgLjyz4fg>cUWoHRu70Uzg91M^K)Um4-k5fjbO)&@?I-v*sE&x?y zZDC}jef9nUv4@t*FM)-EDTWWje_A4JjxPQa*!=l7C zj*Mqq8x;7nDDYFA_|Gbjk*`64-;)9yH39%|kXkT(HDK`l7yj+q+x?MoN#@FmYIDQH zNa>i7DCr4y3^e$BbIlJ<2fjM+tF;8o00AruhYAiJH0R~#TMisJAX!=2N|`_8fF*Os z4k;}w<1$_mJUPN#LZv?dUjSc{o}ONeO+_V5nlz~fXVn8sR~{@k6Nm((qoae7k&yua zPcu}1nE|#fE|<#+aSI2o9XOAM)vUza1Gy>11;y!zQy;!Dd^7k4@M+-KntS)^E$utB z7idrrS~df~<&rk6fr4eG0bJGhb%4t{)9FWb@dx}U3S+QUh9OWAC&1D{0NorIj>s+a zh!X>_18d>jU`Y8)aI30wemid5xbttm`DQQPyPfU(7jb$) zNfMJ99Qa;VLbM?hTzD=DP@E(`d%HY*T|epCqrcoa{4FuZB!B@4IZ;qPfDLNc(gu!V zP!`U3U&g)mto-A$%Vo^iF|hQOj7|m6i-3exYU33+$$4cSS+X@xs=?*ALR=w$Nf2Km z!JGb4!}U@J#s62$m}gu8Kv-~&DIQ^gT(`;Z3zg*M`gd(zWy##U+WZZ)7ld6_^Lnw1 zZOIwm$2VxYB|0wgz=eOisPwVh22`Lw{8(0cyqY7wF;l0`ja{^8c0z7(X}zkl{8sz2 zvpekHzV%G(+~UMDKD|kX^g8zvIi*uKU(?nd&C&7oEd1sK{60)0(B?r?1x)c?2>caq z72q_4x|24RfJa1jkB8|ubU{%lH$20+ADJ%&csi?U_XW<*_pi!B!zh>+g z4VXU~HMHcr&pzU2HGcPMx4YWWjB|qme;Nh!7X7Ccz{uF3z#mM3+Hz!LdtGql;Op;r zL=qdf_LWtY+hVXF*BbI_EyXTgMgRadaY;l$R2#)fLX_fmDh?+HT@ISMQ$wt}2egO* zH0;#)%ySG{p=zhg3{$SAtn4haAL^G13JL@=!PubVld`fhS+Zn_K(oV_lCP%9OB3cu(^ehDA^1yd zs&OLG?pRQ^KjPK!GCsv(tY}AofT4iL9Vjc@7uvOFhxPk)>rJbtL(;{y4{<~ia26jS z#nnNn=y~xKl`S(eDv_fL6D}HrAUm5AX!b?Obc7sP*?VHwuUZkaZ~wtq%ybiRKbq;# zb?DklI%3mai#DeQ8n-wl7@b((Vz%1N9;_-U^?eH1YG5}&6WJ&>0-)Vx&N?&^!RTCaCYzK`Y-DUp^(F zsZ{~e61e4o5s`poB*jYWdI^%~fE+e}E>}-D?8+hYU!zluALVN)JxqixCyM=%Zs1x^SG=q>n!D2!1Eg93jL1=N5aPW!&bO-~th z@31$eS-Y-Yk3V2@x~fcZ*!tfhEmktpVGezW*FJ)d0#=IEZTCQ3XU; za>{A}WEE2j7)}KPH8`}8N%fjB&|$nZnQ(0)DE4AkbU-Z&>uE9%W^w2m!PPwi*+z{T zg>b~aFH)C7#m3zFQeR=tT%&fhpo%;`3iYp3Cp`skI6=cfp)k}XaIrS`~O-E@3 zF`=mVWJySGDyfZ{hmzvsf+;DGiH}M!*`i{BUacl9+bB@aZ-)haLhBY9U=KoOmZBj( z(8cSll(Lc{$<4`;eVH3%!`I^^yO?ugk+|mVrEQ-}C8=3Eu_ZSZuOmTC4$J}IarJ%T zB$HSj1_gdC1^5wWdnc!_EBps{ zKJv<`-TGfFG4;}XUbov??edx;A}rDbq7E6UQIZ<(Q0k7tcnwhqKnZ}ER2Uy%z|aO~ z3@Ci2{?ub&IdV+2E~X!~C+fF05UYL8huX+eD=<#=zN#NmAgf$B0!LS(ZuCyG?-)r8o<_DSo$$up)Cx>Dob2B=eHvQC=9T!ZWKE4dsy3-h0 zT9(Y#a7R->f!;xb1|?u4yqQ=bh&T;K2-!AW&=9M@Q4|u<5aBYRy$`uEJ#H zn+5abqW+c!{4Gt0F1$d*{zatwfuPHfX#)d1a-z7_CPLTh;{;WJZY?wUx z_+tRQ4gfGLtAoqQ_QbGCBm%%~OHPTb+lxsfg(Ic7Tqz*P_oeNvT-Z0KWf8t^42 z6`W(J;|f6}qby*RBBwW$S6Ui6P+l1-cX>mB$`Y}Z>=hqWeUm`A~iG9-~vhuFkqs9B3b6Q|Guxwj#4RsqnKmWa>oMEQ|7 zINp1)5>!=LCPn#s<@*KS99Dx?{jZdUtvZXn;VEKGtS_dBSa53zR0)#t#o;#ww5D1y z0$g%lNjE>Z$lT}|h4-2kZIea`QIa0(kXY#HrJ#eKfex$5Vc8yWp#jh0J3(aZXNNX23|b>F>uOfyk9$h?QpfvRc;*kj)PMGmo-$?;($v~ zqSckzW52yrL5XNdiA!?e^UB@e1Y)4XplpXYhz*0j9|Jvvs}UFU#Jab|YJ+724A&l~ zt*RJuir9p+=KJsDn=dBhAj$9GXWsVMV~a<>@=7`L2s;8ey1%lxf<}R3|5fe(w%cw? z89jRRvbl5Tw#0@;F4fyPajNa~_N5=S_N=vKZgjFjo;oWliz@6?wEs+7Eb)y`feBo% zLOohLshuKHU}M3*2d~VEO=S+BOXhtxM#e$B;hCXB<;f==gJ!d6fH`o2InzWt(KnQ` z90y9A@&h=^WlrEqXz$Sa9z|aO$W(j!>ArS&Ne~>XHtH|jjtQ*UjsuW^Eq4dyK&4mm zs(ey{`gkE{OS#yf6E;bzi=_&x@4Nu0WqEt0B6p`0Ze4a{@-^2KEaK`03C{+rSvA4Q zkGU=vNar@4B|a%#Vp6f8FFsXm1~h?Iv~=bMr#1vmE#`%4B7h<*`cPEChk8)rA_BFF z!JWQ5dz$P^W0LY~#6xLhg1#55h$BI(>9zA`7L)~HD_c__NZMS8d z>=u@7yO!%zt5z*rTej^^T-LJfTFc&h?&o>$=llof`d!zTA9xu#$SN!^0DKZD@q^kb zQP>J8dg;AyR`H$w0(Qp`yj%G;zTe=+z?^gbXFa1+2;TJ!XWbzAb<}y^eq7OO;vHkk ztH8v<0Bm6nAoz*6iU5-}l!H7Dz(1%b!RA#I=2wb~~k^88VIMn%_q^geO*Vhbg zxy=D=eHE;|{a`g{>@jd|r*}GEt``T~woo0*kPV$wlcy)MZ`_ELdhJ)uf#Lbo#-JKP z%(x5zOj27}Y~-qcI8{pt^>L^;0KT8mzb~rB9tC*$n9B;>rX%4>Gwd(wV#`Fy8`;J-5PgsY#vRMaM<#}vw6#L&QsrrH3Ofvv5b}j_&vMQEzj|+I!0kF#7j2R|} zSvU}=PGc!W4IHS{=2An?up2JIY#2$LvEBI=hp%Lb#xvjz_Z(9VcotKpf#E|O18~)z z!U^$Ej13FPf+#X~NsV3gkSEk_n+4ek(k^!M892DdsP78MPeoAj(pQzc*h)2c5uADK zClpGwz30xB$rxEkwq<;zHLXH+4{F89opK)+WBv_pL|s)FksCzIGKInX`Uw;H{PK5t zZDbY-YEl5U1e$9FK3zEGi2E)I2LD@of<;hD*1n);Vc3)lIJ|jjyDmo;X_H6^Pc`ft zCQyiKQ6!P3Orj=~11KxWkwwgxK}^sv;Lx%LAexANIV>0Xl<=r{E$9QVV%MRtrEP6o z80xy(=nl3)Bl-vswlzN`+dN!@ok#;AS_tUqAq0Mh$OQ_`$0n>(FOWqg^Zq~^ff z^X0nrM%(8>El@Mw)SEK|%uN!JZ@$7c?@iHBhXblBY-PQC;^UhNRi z44j7tw29KvN|7aEC@81`1;Vt^RJ=CSiB)q16yBevLwI~fc;}9yvxhFY%~r^$PxJDXJBtG)+wn-0DbGsd z`ovaA0wz;TkH#V~y%r{f_sF~zylQFqqU zf08We>ZZhEh_bCgk^TZ{$5Zb9LH&(2fp}2HI%X6_9iH{kM-A!JLvKB`SVJR&bB(Vy z-7CiCpvK^R08>5-_K@b0?QvBVu|0rOKg2=&<5Vyv3eyZ~_uyS#x(_nWzP%iJDdBbZ zT%DQJ4t7ZtK0rlDCADqYXLNEB>I~$+ba8%TIRmvs6)huh_(8$!lx>bnzuMnW{gkA) zKY)VN0CGTLTG2<3cDuJl50#2SKswMh5BYv}{}J_IsIxZJ+2%H3fi-PB@L_|Iv*(tl ziC?-xMQhy>VL_*Y8Y@qq$s1J)|Fcnxop=8EFKieHiYrTw;`z}1w?)Jhr0Fjhk@u5g zB|rhbFPn2&>8FUN?IrQ#3tp}CWkfI!F(2hR#l^$W#Jv*fmfaYU}*fJ zG^3Sf6XZM+Tk|H&r!oCN;e(_1FM`6qUsfI(X%b=dIYr`#N%WxOUkPRqc&J|TpRLVy zz&3N~m!6)7a9CBlwc^rwhZ!_dH5zVxJ(x}K&s74p=$p_!fWRj=UxBLxUbw@U!LXMk zCn@VMWtpN}} zOf~ZSNq#tpRWKPJ#up!XaS`Lh6n*|G!hdcT7580Zn0exu-;tmq+-)qX%}{0A(orX< z-Eq?Z!^;~GdT!!F0T9ll`t(9e_PKt66Q>XUCt0WF8&cn$0`pMnG4pC3fc}SiT$(in z44^wDih=3=Om60@tmeEWe@=B8LRyv@mb(petMVsxI8@QJB%}x@c}=(Izp+#Sht?mo zD1&(Wn?c;~pvZukM!in~Yp*6juPt74Yn+>LXmSIUe7A_!&U8*{+ur#Q%2k=5bR3c> zB0PZ}JOP}?>kjePg+R`Z(@+efmk;(U`Hgg?B@(&Xa9@gq^FjzwHn=;oLdD`n2CEfw zxRB!Tym>Uu#I&jKTN#Gqisi>(!n|-X0c7DG!U!Mb;QCGH3lBr3P!p76FK6;fj3~!B z-Gn<^FPjCr#zQjJ?QAVVpPATxo2S$aGc>Za%8li2tL~7I&JR^Xs`UpyAM8Tnpq{mF zY7~w1@|Wzg0T_LU;3d1iofXAZWuR-12gu+F!9&YkWs9?6wemBEWXt%@gF|uI6a6LQ zB$Df0lX=qxU+TE=gW09$ zZ%3D~Uyh;I21xnTR4tSX?IOAweViHv?z-A}iaBXv1%CzrB-Uyo&8nh;wkcfEo4{Du zM2*Bo&CAY?QbYfjJ@?VPm;91x=5ZS+oFlJ$=l$hRI-zVA)olH&;&%krXIm~?w*)h- zWTE}hQPR&epon!=gNL+!wr11<9BoH?sh{TKk_MO>VZiGpFf+lOIzsO6m+Z2MsW?wP z7j*vu&nj^b^B^|TcU`o!WL%3h$+PsX@>~ZG!;%395vy91U%xGriLpV1c4|K|K~Fw{ z)nD@n_rbIlv|ZUfKOHFD{z2?Uf&n5gb+g{_OXFPEPbzo{F;`XZjQXj_~QY-^pqWvtA{t93n=n3t04= zGWH%P=v6S{$Yw^Oq5(7ENIwK1Z?VG)cyS`Fv)`H0c&be=q(Q%X83-%gQUsu0KU(zC zAp%TxhLr9tb>;9+5cA5%zUuHzW-_3;I+v|cXcax0=yv`uo6re%2q!8Tg=snO65JqB{&8jh?)cZ26Bn;)be!pnzF6CUa!Z~MIN`q#76$O_j@l3>`1-13+5`W zgKq{d2$vP_>)@i@JcjdNbt{f zDZ;Tm^8!jyZUr8eL~%iXWEfd3?1*)Y`y)z2>uQAI24ko37O<3nBWDbs1on!e*4uRd zCYw3WyLT%mArTCP>!iS()4rDdUO?z2n`P=V>!ag?vjt7k;rG++tDl&2)dzg6_9iGx2!h~8Z z(@)HaWdd7GvW;#5faf4erwSv+Vxvl|lgqMJ`qt12XoFy?IYawH%blb!yxSM{8Ekuu z=k?t$+VaS4t-de!V?CmoA#eT<`&AkI7N|J%5F_|r?03LxqAH?tRT|JWzGy1SYtp;8 z^)ELpB1YFi^O7-YNl8hBDc4Xxy*D4NyXL~8a*I)m?nrI}c0+hQIgV<>Tf-d>x9U8K zVujU7OPI!aycz;!C^aXfR>}}R+iyasfooAC(W6p?4Y9lED6w|5k{%i-)Aj>M*vG3A4^* zck#G7U~(U0IRG(OFji9c5)&nlC_C_^VYWY+cGVQGMjiuaEnRQJvM1a-l_5Vy{`?B! zl>7QoSKH7w2+ACh4EJwQi+>V&T)jBJ(D5oZ3f6ws%l!rG zw#F$0R4b(N?+45le2)W^6)fC*w%UllA9PmA?||N&#hjF7Y%+1r6a`kKsqoruvu)82 zZIZ$Ks&I~a6$5V;ZYfna0r&9_V8kA>CuF@$or5y*@{!-SW>}5|OR^&XNd#2GIfr;T zOb#{(_r?Zs4@gQl!eM6Amm{dx*G^m{0n(CLp)TB}n?cN+W6A4P8#N7~-TvuQZ+?s# zMJm5l%znmNu;ca+#bF+8H^7-$hVl+9;G@hRE{g^Z6We@;5^`x&bY8-Mwuw?}>e;Pa zfjbDS&KjR5<6N@A-%WA7k;Hsu$xTi%Anx3JA{-lrc@uC3d9vg7v1t>jH&%~tOJm8j z;;9&-eiDNSEM2C$l1|pJKcYchcS_b{tnpj<$Na&Y0Vhknl-ddjgdzv}T8k{xuEcd^ z{T$M!mokEwX@XXA&Qa%xS9e+M_2>l{J~a&4EDKxr1J4fqWcorCn@sVS{doQKN{S?Z z%fx@RFIo)r5ob-GG%0+A0uVLSX|O+fElR#6_7-7V3sLu0ihOty=gc@#{^<#O{X(>f zF^wJv?funknDQPvgfvYH^PrP*Dika-EI1Ek8pIoU!gx}Z?e>@MkB>^#q(A2b3-8Kv z=PYoOe$(tF7xL=2B$c&EbL;gzMaT8=xUnHPMB`BDxki=`EK2stU|fxvZPN-I3I@j= z_rc}jiEcZ)BdCD^`GGT-C|uQp6tBjitL9*X^b~@l@y(6S&>yE21+Q=ZH?6gXNt&Pa zGonU>w~^hw`;G=)w&Ps~5@xyBX=4#qmjk4k_8O+t!A@Cme{S?2VINFFWC6#gK;DoTQ&D09@PRA)u8HwP^}S2}?iSE*3aB`68S`1f@2 zdxS|dENOOlYrWVk%Cp%9ra>g3HO6ZX{BPwT{g0;K5m`bak2_T)8UO?TF2Kj0KgmQ~lFd zdRMK{v!}m5+)vAc^6BwaZn43E7}5*1oG_cTeU*H&$dZ^d9N}q3IB^Gw%yu)vOhYOgwCSa?Ej; z`towSS!4y|#E=Af9Hn1hTwsj=99l;iL>a&xfc+XTsf|>`di(edi^%G z;Qr6+XjBDLgz*Ty4W9&**Db-WIj@?mf`-5Xi1RR8^zJ7eu)66;<+*%&IEa9{x_tYF z)Z}klaR3*OE4sjjIb=h7V9g05AXeJfOH($#X7ZW7eQ1V8vfEFdl9hcup&U#lAru`Q z>x4J-OQB79$Bv;t`Gc3m@#i}^(Qh5~79iMTfuj!WMQ?k6u+!pS4;e0%5KO`a6=-MO z|HnY!26wHqR^*Puc^!T_eJZ^mX?WHZ+7zR~pUT!&^X`9u`gd$|q0|Mt;qfUg)$ruW z#B8T9Yf{y{B!eF7M%uoi`9~|wXd)%baWG!z*zsawi0yNE+(t-hG|!J5$o|kg2XCVP z6VHWd2@hxZ=E!9fXln6140sSP_tro#6~5Vka!B2vWP-)P7fPS)Bu0v0L(?Ld)s|4W zL2($3;4F+3M0gAQ*io9=*DWUB-C0D-{a>g>#xeK1;qvG}HzzqNgl>$hei{H!Y!NN))-WwS+$KrRmG|oaCEB15U{Bnf(MpEUi_8GsXvjuB)~&)Ax1w zxmptw_#xZ4$I|hB1_}g!fxv6iCSg3u%?DE%!0FTajC&{}6D$9W9st8F zVtM~P^d{!A{1!mVF$ANk8_Ck>iRTgeMLH!F18T>M47#A&&!L(o1IM|>&<)BcnK!9q zl?+R|v@N`>q(D4}jxv9lE$&58Beq~R zr?P_XR$te%7;i^|1lkusq3o*=wZnZqrj!Pq0dU;B9 zP{udLk_@oF*Fbd`^NAOzUI?=qq6YLB7_?}Qy{1V=3d!Aj^W^8`Ek*U|BEq(j*lg;@*49rG6wZMX@ zv`wZq31Aou0z8yw$BE+FrRLr(?0xy&cA;XyARVd!R81@UJppHG`v+94~ z9KFwZI?_s+>t5(%4n#SmQv&U#-Fd%MPM%5*etiJ1?dv{f$VbH#8Cwq5DzLVZlIl`I zwHMF6pYSs5^g&$zqSd`rZY5*?l`a5pVty*(A-3XXGF5}*K`U_FbeLutG7bsuEn;44 z{>95|CBcgv9@F?i}ur*!578&njjDXprM>1bq zTT?z70#+OS!y`0>EYfVEG8h8H3{el2#>f8)(9_ynZAOgHugEj5Mgp_}?5BLHZrvN1 zstI9WV87wk;qFw3V8^QEA}5_08f@w$?=Rgff!fnz-bp#WvapU=HED+C*Xxjv!Ui0hbr!!=i2k5ZOc|anY2;P6gF}kl^AOiMwrg3VKWs<^+o+ zQ^NlPr)94eS-XB2805n6%7)2lC!T_y)qn34D}3lc1Uj#U1?{i+3zy!v`wZdBHdz$g*V&I=EfQY$ zOdjNa#&AR~NLF^e96DS-JJgPrUkE7tx24gVxtKXHU3)8)U%bAJd8y+Yf z&W($Vsx&DI%oUEji!D&v?i>zfM*Fh5*0imzVpWgjf!L)vKnV8PNH77}`7~3`81iIe zDFlSnDjJ2wUIV%(GjtNG9~Bb_?6{N2D4Dsj_YXBx$i^Z)ZLinS*h%qdnORt_yPpoT z7oqFqdY^cR_<%;lR{hlDA^U$`^KZPFXOrBTP<5aGeal36kI77G*=uWvRz%33_EiZDKO)&HxHjb`WXFB))s%sVnK8T^{W}D%=PM0k3_}*4FIPED4 zzBT>c&pe7yfC}2t@$to3Y2>JJ+~C@t7NDN?O~2-OD(;7@>*JzEk?vzVFlilS7W4yB zD0Dloz-MQkVJ~L|h&s#Y9usQ64!;I)h444iB(N&se)rs-uCSQIOqPBAu%TQJt6v$` z>=p$+`Ad{DD5Q*YQD@PZiJoJ~D{_m!*FLv3>E2h)Qz)XCOX8Bhj^~yqX1SPak4DI@ zf8KqN)^}f3;=ML7!l!{ez>{M50!=g-{lQP!TLMPdKLy< ztrBUdsa+}S+w1q!ryJ7{6BCQM`c${K3qrxPtz!s}|G^{?8oN>y0Ccb)Lk5W9_z9Ke z!Q2c|AQEa0SMFA8!toZv^fm~3v%yD<>Mb4if4)bd`svU=%@lG-4uSRx&@BvzX{4Am4OStzvv}ce8P49rSNUM*P9!ei)0iX~1jA^et{9u>zeLO*W8U|Sm z2+~mDzYeuazf<%R_yud{UPMO)BIwYQ&K`(GUN>Wn@9i6MzS<$n(DM*+E|a6F{~_(y z4?oqZbKkTk$3$wrYzF75eTVvqe>afy0s8Usa{4`DufNxy!ZKD9AJqNslwK>tkuaOf z#%swv@v9S9a$(k1?buh0*{$B^G-cBdW|~bN1H_;-%gO+;3*LX<2xZHny-(-uSSI8! zNksjcaMjT~`pmLOBB4clZ_A(DoOv#LtN)%wZ#WE@CQ=F06v&(9wJwIU<2ah}r=Q}K zK%qYt2@zxoF9wr@oNZg11s0QqNrHy_5_=Y?oAjdKDTf+nxqUfSn~?j$vVRl5nT+}G zCbUb;uD*!hg)sL$mz~i**vr_*haqQp_I=O-h zget0@&B@Ho*`2F-Ok}O=Y8ORhM&mkv(L^(ZcONiw%WF4|DAt^ILsMe;`p4l)2Y#Ek zJ4=9vV&JruNLF0uX)hYAhgwd4yY8bCZVhLwHV?Ct*;BxLs-k0L#O|9Uo58_3$}i`!T__*sCAwf0oK}|2KTRe?Xb}d^cY{Miq@w=9kZfx#j;yG#!H?Af^c((zJE~ zXF)L1loe0Fyp1ITMkLl6>DI62(`&dzJlUu$75V7i)g*XBkV&8ZvQ;J|}=W4L}8Rl7v6~)4U#PavK8A4sF!G?(CQoU3c_e2NKPmGQit= zrFQ563+Mk+ND@Imw`;#9h;V)(#DzcQu_yTL%tQy1LPVgzVW}qN?0~nxAk^d|pZXcN zWtOGO5L5eX0II)6D;JmI*2otv+WzA)49f;-H3fwW^-K4xXFW_2paar9ra{V|f_){a zld()gV>z9c%5$EkWHl(PS#(#vaRAxeNNTj{tTL*XCJ4GyKlw#SDkF|zV8b?_IYyu;ny}{vsf1baH z*naWOc+drWP$0g2j(}0qL{PQSF#q~l0$n#8H*e8ehoyT2y_k$kumJB%9r(9Hq<$?_ zj5e7tVx5jN=&JdH!xpTNQ#TeOhzQg3pX7j)#Cy<6yHg>XQ3vQtO@@h7ub+VMztyw- z@0X%QdNJ03UgWtdUsU)pDF2O)hexCQ9j3B_Vd{^YB$Wz=H&m(Qv-amPXMmxuOme%2 z^|+16L|Lwk?eW>47g9cF=Nlnb%Y(V67sfc^yALqmF%fBW(m@Xo5_>z+v0)M+9Ux#( z0GiEzqagx(93s4DO#%Kc2K6^#OX}aH&`f-b@_HaZc?*HXyzPX}@}0PJ*q|y;5{(OE z0*bC_N_U>ss%NZI2_|IPwN1+LX@})*Ng2oBOM~9?G4|ArCoPQ&pf?fASliB|GI?+G zo;?BQe5likB)TC@J)mm-3hP>%7V+yxxoA;t{j5a?HkCE+&U$V2|3ri(BBwQ_6Y8x!vzud!1#hCl%FEACcj1&TNpxXHCDClhunyFd?xGp+5Z;L zL7XT|R561ivkOKxIqO*XxL!}F112M2Ys7D?kHrNAJXa%95AYV6Sq47>p2$7+hMDKs z@Y4nh%2ZG>0J@`GptRPuRYw177CKZ&>pJR2^ZX*<$>`WgjckXzR)o4!Cy1q1d6Ol- z46pt<7bQS4nh1b*4R{5nr|n{Ycn8H|CvttM_t?O^eq>J{xuF$Lx&6+U)NWJSHa1q= z)g-T7W5l}FcprUkP#b;Y|8KBWQ0e*Mm?JiuFa36Sl8%|)h{hs0G_f8Tm_6k9Vs=mW z)LVK+OUffnI|5fXC;nv{uRhNscowlnG|0Nf<0|qztp>39MU(Qq`Em?=UKd>wp4_wo$FW+^<;Qarkia>TRO36*O8 z6O}Y06)ak!-og3b6C8uy)TYWMq%jAlgq6E7-+yfse@)G*D-;#$eJ74?FIIm*r~8ioGNl`u^^A z{|nBh+y9nMh4x9{96LXOo&~_h0sNGD2f3U)q;Iro6MMOejn{9ze0+{0C-t^1K1a#x zjBuZAX2e~k-CN3om?Xd;Y`>xQcovTR|5($9HC&Xs+SSfC0 z^4b{p*v`IsSXdO0cwNqqt~bbNMtzSiIWdYB1vHoskoMJ1*N!g8uF(n7%BU*DCmQ*t zHne_VLZn{H%5IdK>fYDSIE}^Thg89j@ZvSW22k{zQgX!etT+I1_!48#2*Jwr(?|Hd z>CeH)5q~F8o{U_>Xvv~9#G9EFrM%2&62CMSEmoESTq2zViyeAC;@VMhI#UkOB9MeyR|O;y>2%?{9<<|sTFkgglH3RyXhnS z${D~1;lK#wuHl3eT_S>J7_J-%U@r7P7MRV*(Elg%n5u0{=K`H3eFBJ3w$en>2}9+zmT_9LKYv56qyX0bB^%B_ag2MebLHkMD~IFsXYPToPW&fr8sU8sr+4+4~GThd6@1 zN}kWl*}*5^alJfK%r9md7u%Q-^YDk)Wvk6lo8#5}={nrw7wzn)o$(Bxt)9SYR6-7E zYJ!NfsZQvQ!c+}Z3I_UkDH6&3xAB9fp1ii69hgkOF&n_Mt19%ToVdj>TZl`{&5x_2 zb)m;Y-p<_3?i0I>P6JYYXBy4P+kgkgTYX4`T?nSsYqCP(c zAdjbPG86>*xvq?Gi}cF`@YygOkFZSmeuT+Og-W^I6j!$$+=H?S)2awC&EU%54g?IP zElYpX|JGJ9j?~wOY;Ei6h0lZ_hB#BAhuSzq&|u&Q)XhU(VGAnzed|Wh7|wUCKj=Ke?T=i4>wp*LV=%6q zP97AnTj0Y6@mh|F9w)&LEtHs-PQ!`zFgU`6Eg}GPz&et8*Cx3OsVvT(j%1YH%p zLHGtMqEKxidDOjWM(qljuuBtthrLB1%C^oRD&yW!oCZlul7nzFWhq>74ERZ4{Mvar zTSMC6pJY*CzR@%-@pIXxc9-r~BCmM%uij8m6?rj0ox?YdV?6FSC?Y=MKTn%@mni;! zizw(-{#pnz%P~orLc8P?g#1VN6Q=*8*}waA-jcO#gY6F5fQQ@fvPK1yiB7J@!Q*o) zi@!;v<^k(VAIh+lCch<5vEvl?qYG{ℜpPg+CvnD0t0~UDL?n);DhzE_V~?2B0P= zp-K^cZR=8~NAi-Ej~0TH+RXKXLqC)DYXx4ge^z5~Q!ab{NVa`!G3-Odsgw;3>$|7j3!1W{*r7{Cr zg#0KT-OwOMXH~WPM)!ZooSGBVZC2wQ4PpK*mm589Z`yRANxaH! z{sF>)r7sm?ZG9cK86EeUd+Yz1`dJh}Us!yUvMkkqpIBKK9u;ibUJi0YP02!~j#O6~ z50ac block. +(function () { + "use strict"; + + function addCopyButton(block) { + var button = document.createElement("button"); + button.className = "copybutton"; + button.title = "Copy"; + button.setAttribute("aria-label", "Copy code to clipboard"); + button.innerHTML = + ''; + + button.addEventListener("click", function () { + var code = block.querySelector("pre").innerText; + navigator.clipboard.writeText(code).then( + function () { + button.classList.add("copied"); + setTimeout(function () { + button.classList.remove("copied"); + }, 2000); + }, + function () { + // Fallback for older browsers + var ta = document.createElement("textarea"); + ta.value = code; + ta.style.position = "fixed"; + ta.style.opacity = "0"; + document.body.appendChild(ta); + ta.focus(); + ta.select(); + document.execCommand("copy"); + document.body.removeChild(ta); + button.classList.add("copied"); + setTimeout(function () { + button.classList.remove("copied"); + }, 2000); + } + ); + }); + + block.style.position = "relative"; + block.appendChild(button); + } + + document.addEventListener("DOMContentLoaded", function () { + document.querySelectorAll("div.highlight").forEach(addCopyButton); + }); +})(); diff --git a/llvm/docs/_static/custom.css b/llvm/docs/_static/custom.css new file mode 100644 index 0000000000000..60b2b5c9be1a7 --- /dev/null +++ b/llvm/docs/_static/custom.css @@ -0,0 +1,62 @@ +/* Enable flexible wide-viewing for Furo theme. */ +:root { + /* Remove Furo's default max-width for the content area. */ + --content-width: none; +} + +/* These settings seem to reasonably balance between readability and content + * density for wide screens. */ +.page .sidebar-drawer { + width: unset; +} +.main .toc-drawer { + min-width: 15em; +} + +/* Ensure the main content area is allowed to shrink/not-overflow + its grid cell, preventing it from pushing the TOC sidebar away. */ +.main, .content { + min-width: 0; + max-width: 100%; + + /* Remove default width setting from furo's content. */ + width: unset; +} + +/* Disable small margin added by various UA stylesheets to prevent + * scrolling artifacts. */ +body { + margin: 0; +} + +/* Allow the top-level container to fill the entire browser width. */ +.page { + max-width: none; +} + +/* Ensure wide tables and code blocks have their own scrollbars + instead of forcing the container to expand beyond the viewport. */ +.content table, +.content .literal-block, +.content .highlight { + max-width: 100%; + overflow-x: auto; + display: block; +} + +/* Ensure paragraphs wrap within the content area. */ +.content p { + overflow-wrap: break-word; +} + +/* Printing support. */ +@media print { + pre { + white-space: pre-wrap !important; + } + .content-icon-container, + .skip-to-content, + .back-to-top { + display: none !important; + } +} diff --git a/llvm/docs/conf.py b/llvm/docs/conf.py index a2e11e3d0b033..f12ba64ec1203 100644 --- a/llvm/docs/conf.py +++ b/llvm/docs/conf.py @@ -77,26 +77,30 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = "llvm-theme" +html_theme = "furo" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -html_theme_options = {"nosidebar": False} +html_theme_options = { + "source_repository": "https://github.com/llvm/llvm-project", + "source_branch": "main", + "source_directory": "llvm/docs/", +} # Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ["_themes"] +# html_theme_path = ["_themes"] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -# html_title = None +html_title = "LLVM" # A shorter title for the navigation bar. Default is the same as html_title. # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -# html_logo = None +html_logo = "_static/LLVMWyvernSmall.png" # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -108,6 +112,13 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] +html_js_files = ["copybutton.js"] + +html_css_files = [ + "copybutton.css", + "custom.css", +] + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = "%Y-%m-%d" @@ -116,16 +127,6 @@ # typographically correct entities. # html_use_smartypants = True -# Custom sidebar templates, maps document names to template names. - -html_sidebars = { - "**": [ - "indexsidebar.html", - "sourcelink.html", - "searchbox.html", - ] -} - # Additional templates that should be rendered to pages, maps page names to # template names. # html_additional_pages = {} diff --git a/llvm/docs/tutorial/BuildingAJIT1.rst b/llvm/docs/tutorial/BuildingAJIT1.rst index 8d79eb9eb3ca2..52fc943aa687a 100644 --- a/llvm/docs/tutorial/BuildingAJIT1.rst +++ b/llvm/docs/tutorial/BuildingAJIT1.rst @@ -2,9 +2,6 @@ Building a JIT: Starting out with KaleidoscopeJIT ======================================================= -.. contents:: - :local: - Chapter 1 Introduction ====================== diff --git a/llvm/docs/tutorial/BuildingAJIT2.rst b/llvm/docs/tutorial/BuildingAJIT2.rst index b8d397662576e..580e82220ad1c 100644 --- a/llvm/docs/tutorial/BuildingAJIT2.rst +++ b/llvm/docs/tutorial/BuildingAJIT2.rst @@ -2,9 +2,6 @@ Building a JIT: Adding Optimizations -- An introduction to ORC Layers ===================================================================== -.. contents:: - :local: - **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/BuildingAJIT3.rst b/llvm/docs/tutorial/BuildingAJIT3.rst index d4b3e6fb8eb36..3e8d24b9e92bd 100644 --- a/llvm/docs/tutorial/BuildingAJIT3.rst +++ b/llvm/docs/tutorial/BuildingAJIT3.rst @@ -2,9 +2,6 @@ Building a JIT: Per-function Lazy Compilation ============================================= -.. contents:: - :local: - **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/BuildingAJIT4.rst b/llvm/docs/tutorial/BuildingAJIT4.rst index 6eb3d52ccb8ab..e4ba22b183385 100644 --- a/llvm/docs/tutorial/BuildingAJIT4.rst +++ b/llvm/docs/tutorial/BuildingAJIT4.rst @@ -2,9 +2,6 @@ Building a JIT: Extreme Laziness - Using LazyReexports to JIT from ASTs ======================================================================= -.. contents:: - :local: - **This tutorial is under active development. It is incomplete and details may change frequently.** Nonetheless we invite you to try it out as it stands, and we welcome any feedback. diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst index 71ba9322817e0..da8d5ba1525bf 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.rst @@ -2,9 +2,6 @@ Kaleidoscope: Kaleidoscope Introduction and the Lexer ===================================================== -.. contents:: - :local: - The Kaleidoscope Language ========================= diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst index eeb47a255a622..543bf58248948 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.rst @@ -2,9 +2,6 @@ Kaleidoscope: Implementing a Parser and AST =========================================== -.. contents:: - :local: - Chapter 2 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst index 123f122af77e4..94dae2fb7e3dc 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.rst @@ -2,9 +2,6 @@ Kaleidoscope: Code generation to LLVM IR ======================================== -.. contents:: - :local: - Chapter 3 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst index 3d954e744f5c8..d36cb05035c8b 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.rst @@ -2,9 +2,6 @@ Kaleidoscope: Adding JIT and Optimizer Support ============================================== -.. contents:: - :local: - Chapter 4 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst index 0039547e8c7ba..e0bf85b3a3667 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl05.rst @@ -2,9 +2,6 @@ Kaleidoscope: Extending the Language: Control Flow ================================================== -.. contents:: - :local: - Chapter 5 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst index 066693eb963a5..f78943b98a1a6 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl06.rst @@ -2,9 +2,6 @@ Kaleidoscope: Extending the Language: User-defined Operators ============================================================ -.. contents:: - :local: - Chapter 6 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst index f7e7572367448..0e815786a30b0 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl07.rst @@ -2,9 +2,6 @@ Kaleidoscope: Extending the Language: Mutable Variables ======================================================= -.. contents:: - :local: - Chapter 7 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst index 2e3d4ed0a3087..cc5aadb6e2dbf 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl08.rst @@ -2,9 +2,6 @@ Kaleidoscope: Compiling to Object Code ======================================== -.. contents:: - :local: - Chapter 8 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst index a88b6ed48e8d4..5d25620372633 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl09.rst @@ -2,9 +2,6 @@ Kaleidoscope: Adding Debug Information ====================================== -.. contents:: - :local: - Chapter 9 Introduction ====================== diff --git a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst index a739936b86608..b4c7edbd1fa40 100644 --- a/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst +++ b/llvm/docs/tutorial/MyFirstLanguageFrontend/LangImpl10.rst @@ -2,9 +2,6 @@ Kaleidoscope: Conclusion and other useful LLVM tidbits ====================================================== -.. contents:: - :local: - Tutorial Conclusion =================== From 1eb67aa8bfe49e8f5e926054af899bb56ad4d8f3 Mon Sep 17 00:00:00 2001 From: Prabhu Rajasekaran Date: Thu, 9 Jul 2026 16:18:59 -0700 Subject: [PATCH 044/125] [libc] Disable baremetal modular printf (#208576) This reverts commit a14d084bbb1a7261d8a71c56120159abb6af330b. Though the modular printf works as intented, we noticed a few challenges using this feature. Without diagnostic help it is difficult to understand which "modules" got linked in and why. Disabling this to be the default setting until this is sorted. --- libc/config/baremetal/config.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libc/config/baremetal/config.json b/libc/config/baremetal/config.json index 5ccc327693084..1c52cd0093e1c 100644 --- a/libc/config/baremetal/config.json +++ b/libc/config/baremetal/config.json @@ -13,6 +13,9 @@ "LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": { "value": true }, + "LIBC_CONF_PRINTF_DISABLE_FLOAT": { + "value": true + }, "LIBC_CONF_PRINTF_DISABLE_INDEX_MODE": { "value": true }, @@ -30,12 +33,6 @@ }, "LIBC_COPT_PRINTF_DISABLE_BITINT": { "value": true - }, - "LIBC_CONF_PRINTF_MODULAR": { - "value": true - }, - "LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_FLOAT320": { - "value": true } }, "scanf": { From 09ad7f10b0e154118e1f356f189e06ebd5bab4e2 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Thu, 9 Jul 2026 16:22:51 -0700 Subject: [PATCH 045/125] [gn build] Port commits (#208584) 0f9f5a2aba97 a1fcdd1a7a69 c0ddc3c5ce0e cfa5d6f59db9 --- llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn | 4 ++++ llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn | 1 + llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn | 1 + .../lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn | 1 + .../secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn | 1 + llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn | 1 + llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn | 1 + 7 files changed, 10 insertions(+) diff --git a/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn index 1fd0bcc1f6cb9..a6a8b2e812cff 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn @@ -197,6 +197,10 @@ clang_tablegen("BuiltinsX86_64") { args = [ "-gen-clang-builtins" ] } +clang_tablegen("BuiltinsZOS") { + args = [ "-gen-clang-builtins" ] +} + clang_tablegen("BuiltinTemplates") { args = [ "-gen-clang-builtin-templates" ] } diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn index 181b2a2b4b2c1..814ee696396ac 100644 --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -39,6 +39,7 @@ static_library("Basic") { "//clang/include/clang/Basic:BuiltinsSystemZ", "//clang/include/clang/Basic:BuiltinsX86", "//clang/include/clang/Basic:BuiltinsX86_64", + "//clang/include/clang/Basic:BuiltinsZOS", "//clang/include/clang/Basic:DiagnosticGroups", "//clang/include/clang/Basic:DiagnosticStableIDs", "//clang/include/clang/Basic:RegularKeywordAttrInfo", diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn index f3ec70354a3f8..b9e755973053b 100644 --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -402,6 +402,7 @@ copy("Headers") { "zos_wrappers/locale.h", "zos_wrappers/math.h", "zos_wrappers/poll.h", + "zos_wrappers/stdlib.h", "zos_wrappers/string.h", "zos_wrappers/time.h", "zos_wrappers/variant.h", diff --git a/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn index cf00808a282fc..c68ea997b84ca 100644 --- a/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/ScalableStaticAnalysis/SourceTransformation/BUILD.gn @@ -9,6 +9,7 @@ static_library("SourceTransformation") { "//llvm/lib/Support", ] sources = [ + "SARIFTransformationReportFormat.cpp", "TransformationRegistry.cpp", "YAMLSourceEditFormat.cpp", ] diff --git a/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn index 9ed4ba1caea63..be0ba3213fe19 100644 --- a/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/unittests/ScalableStaticAnalysis/BUILD.gn @@ -48,6 +48,7 @@ unittest("ClangScalableAnalysisTests") { "Serialization/JSONFormatTest/TUSummaryTest.cpp", "SourceTransformation/EmitterTest.cpp", "SourceTransformation/RegistryTest.cpp", + "SourceTransformation/SARIFFormatTest.cpp", "SourceTransformation/YAMLFormatTest.cpp", "SummaryData/SummaryDataTest.cpp", "SummaryNameTest.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn index 41f777a3c6d07..9e80699d585f8 100644 --- a/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ABI/BUILD.gn @@ -10,6 +10,7 @@ static_library("ABI") { "IRTypeMapper.cpp", "TargetInfo.cpp", "Targets/BPF.cpp", + "Targets/X86.cpp", "Types.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn index 45553cd03162e..a8891dee19ffa 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn @@ -6,6 +6,7 @@ unittest("DemangleTests") { "DLangDemangleTest.cpp", "DemangleTest.cpp", "ItaniumDemangleTest.cpp", + "MicrosoftDemangleTest.cpp", "OutputBufferTest.cpp", "PartialDemangleTest.cpp", "RustDemangleTest.cpp", From f40ad8fcf0b4914409ce46ef7b5287b8eb4de609 Mon Sep 17 00:00:00 2001 From: macurtis-amd Date: Thu, 9 Jul 2026 18:26:49 -0500 Subject: [PATCH 046/125] [Clang][AMDGPU] Add __builtin_amdgcn_s_buffer_load_ (#203352) Expose `llvm.amdgcn.s.buffer.load` intrinsic overloads for OpenCL via `__builtin_amdgcn_s_buffer_load_*` builtins. Function prototypes: ``` __builtin_amdgcn_s_buffer_load_( v4i32 rsrc, // 4-dword buffer resource in SGPRs int offset, // byte offset from the base of the buffer int aux); // cache-policy, control flags. Must be compile-time const. ``` Where: ``` return-type suffix ---------------- ------ char i8 unsigned char u8 short i16 unsigned short u16 int i32 half f16 float f32 v2i8 v2i8 v3i8 v3i8 v4i8 v4i8 v2i32 v2i32 v3i32 v3i32 v4i32 v4i32 v8i32 v8i32 v16i32 v16i32 v2f16 v2f16 v3f16 v3f16 v4f16 v4f16 v2f32 v2f32 v3f32 v3f32 v4f32 v4f32 v8f32 v8f32 v16f32 v16f32 ``` --- clang/docs/AMDGPUSupport.rst | 7 + clang/include/clang/Basic/BuiltinsAMDGPU.td | 30 ++ .../include/clang/Basic/BuiltinsAMDGPUDocs.td | 51 ++++ clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp | 40 +++ .../builtins-amdgcn-s-buffer-load.cl | 286 ++++++++++++++++++ .../builtins-amdgcn-s-buffer-load-error.cl | 125 ++++++++ 6 files changed, 539 insertions(+) create mode 100644 clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl create mode 100644 clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl diff --git a/clang/docs/AMDGPUSupport.rst b/clang/docs/AMDGPUSupport.rst index 18e3de8abe92a..8ca537fa5d729 100644 --- a/clang/docs/AMDGPUSupport.rst +++ b/clang/docs/AMDGPUSupport.rst @@ -57,3 +57,10 @@ Predefined Macros - Defined if FP64 instruction is available (deprecated). Please note that the specific architecture and feature names will vary depending on the GPU. Also, some macros are deprecated and may be removed in future releases. + + +Target-Specific Builtins +======================== + +Clang exposes AMDGPU hardware intrinsics as target-specific builtins with the +``__builtin_amdgcn_`` prefix. These are documented in :doc:`AMDGPUBuiltinReference`. diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.td b/clang/include/clang/Basic/BuiltinsAMDGPU.td index 306af993fd869..8c64116066971 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.td +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.td @@ -242,6 +242,10 @@ def __builtin_amdgcn_qsad_pk_u16_u8 : AMDGPUBuiltin<"uint64_t(uint64_t, unsigned def __builtin_amdgcn_mqsad_pk_u16_u8 : AMDGPUBuiltin<"uint64_t(uint64_t, unsigned int, uint64_t)", [Const], "mqsad-pk-insts">; def __builtin_amdgcn_mqsad_u32_u8 : AMDGPUBuiltin<"_ExtVector<4, unsigned int>(uint64_t, unsigned int, _ExtVector<4, unsigned int>)", [Const], "mqsad-insts">; +//===----------------------------------------------------------------------===// +// Buffer builtins. +//===----------------------------------------------------------------------===// + def __builtin_amdgcn_make_buffer_rsrc : AMDGPUBuiltin<"__amdgpu_buffer_rsrc_t(void *, short, int64_t, int)", [Const]>; def __builtin_amdgcn_raw_buffer_store_b8 : AMDGPUBuiltin<"void(unsigned char, __amdgpu_buffer_rsrc_t, int, int, _Constant int)">; def __builtin_amdgcn_raw_buffer_store_b16 : AMDGPUBuiltin<"void(unsigned short, __amdgpu_buffer_rsrc_t, int, int, _Constant int)">; @@ -280,6 +284,32 @@ def __builtin_amdgcn_raw_ptr_buffer_load_async_lds : AMDGPUBuiltin<"void(__amdgp def __builtin_amdgcn_struct_ptr_buffer_load_lds : AMDGPUBuiltin<"void(__amdgpu_buffer_rsrc_t, void address_space<3> *, _Constant unsigned int, int, int, int, _Constant int, _Constant int)", [], "vmem-to-lds-load-insts">; def __builtin_amdgcn_struct_ptr_buffer_load_async_lds : AMDGPUBuiltin<"void(__amdgpu_buffer_rsrc_t, void address_space<3> *, _Constant unsigned int, int, int, int, _Constant int, _Constant int)", [], "vmem-to-lds-load-insts">; +let Documentation = [DocSBufferLoad], ArgNames = ["rsrc", "offset", "aux"] in { +def __builtin_amdgcn_s_buffer_load_i32 : AMDGPUBuiltin<"int(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2i32 : AMDGPUBuiltin<"_Vector<2, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3i32 : AMDGPUBuiltin<"_Vector<3, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4i32 : AMDGPUBuiltin<"_Vector<4, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v8i32 : AMDGPUBuiltin<"_Vector<8, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v16i32 : AMDGPUBuiltin<"_Vector<16, int>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_f32 : AMDGPUBuiltin<"float(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2f32 : AMDGPUBuiltin<"_Vector<2, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3f32 : AMDGPUBuiltin<"_Vector<3, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4f32 : AMDGPUBuiltin<"_Vector<4, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v8f32 : AMDGPUBuiltin<"_Vector<8, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v16f32 : AMDGPUBuiltin<"_Vector<16, float>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_i8 : AMDGPUBuiltin<"char(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_u8 : AMDGPUBuiltin<"unsigned char(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_i16 : AMDGPUBuiltin<"short(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_u16 : AMDGPUBuiltin<"unsigned short(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2i8 : AMDGPUBuiltin<"_Vector<2, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3i8 : AMDGPUBuiltin<"_Vector<3, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4i8 : AMDGPUBuiltin<"_Vector<4, char>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_f16 : AMDGPUBuiltin<"_Float16(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v2f16 : AMDGPUBuiltin<"_Vector<2, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v3f16 : AMDGPUBuiltin<"_Vector<3, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +def __builtin_amdgcn_s_buffer_load_v4f16 : AMDGPUBuiltin<"_Vector<4, _Float16>(__amdgpu_buffer_rsrc_t, int, _Constant int)", [Const]>; +} + //===----------------------------------------------------------------------===// // Global Available/Visible memory accesses. //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td b/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td index c8a1b5a824f53..c78c8ec291eef 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td +++ b/clang/include/clang/Basic/BuiltinsAMDGPUDocs.td @@ -711,3 +711,54 @@ of the output. The operand must be uniform across the wavefront. A divergent value gives an undefined result. }]; } + +//===----------------------------------------------------------------------===// +// S-Buffer Load Builtins +//===----------------------------------------------------------------------===// + +def DocCatSBufferLoad : DocumentationCategory<"S-Buffer Load Builtins"> { + let Content = [{ +These builtins lower to ``llvm.amdgcn.s.buffer.load`` and issue an +``s_buffer_load`` when the byte offset is uniform across the wavefront. +When the offset is divergent, the backend may lower to a ``buffer_load``. + +.. warning:: + + These builtins should generally be avoided. They must only be used to emit + ``s_buffer_load`` instructions that access memory not modified during kernel + execution. ``s_buffer_load`` uses a separate cache that is not coherent with + the caches used by other load and store operations. The compiler does not + verify the alignment requirements imposed by ``s_buffer_load``. However, + because automatic promotion of ``buffer_load`` to ``s_buffer_load`` where + legal is not yet fully implemented, these builtins are provided so that + programmers can use such load operations directly. + +These builtins take the buffer resource as ``__amdgpu_buffer_rsrc_t``, which +can be created with ``__builtin_amdgcn_make_buffer_rsrc``. The backend +lowers the resource to the 4-dword SGPR descriptor required by +``llvm.amdgcn.s.buffer.load``. + +The return type selects the load width. Separate builtins are provided for +each supported scalar and vector element type. +}]; +} + +def DocSBufferLoad : Documentation { + let Category = DocCatSBufferLoad; + let Content = [{ +Loads data from a buffer using an SGPR buffer descriptor. + +- ``rsrc``: buffer resource descriptor. +- ``offset``: byte offset from the base of the buffer. May be variable; a + uniform offset enables ``s_buffer_load`` selection. +- ``aux``: cache-policy and control flags. Must be a compile-time constant. + The encoding is target-dependent. Common fields include: + + - Pre-GFX12: bit 0 = glc, bit 1 = slc, bit 2 = dlc (GFX10/GFX11), bit 3 = + swz, bit 4 = scc (GFX90a). + - GFX942: bit 0 = sc0, bit 1 = nt, bit 3 = swz, bit 4 = sc1. + - GFX12+: bits [0-2] = th, bits [3-4] = scope, bit 6 = swz. + + The volatile bit is not permitted for this intrinsic. +}]; +} diff --git a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp index 227a2c4d33bdd..66e4e688e33ee 100644 --- a/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/AMDGPU.cpp @@ -31,6 +31,22 @@ using namespace llvm; namespace { +static Value *emitAMDGPUSBufferLoadBuiltin(CodeGenFunction &CGF, + const CallExpr *E) { + llvm::Type *RetTy = CGF.ConvertType(E->getType()); + Function *F = CGF.CGM.getIntrinsic(Intrinsic::amdgcn_s_buffer_load, RetTy); + + Value *RsrcPtr = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Type *I128Ty = llvm::IntegerType::get(CGF.getLLVMContext(), 128); + llvm::Type *RsrcVecTy = + llvm::FixedVectorType::get(CGF.Builder.getInt32Ty(), 4); + Value *RsrcInt = CGF.Builder.CreatePtrToInt(RsrcPtr, I128Ty); + Value *Rsrc = CGF.Builder.CreateBitCast(RsrcInt, RsrcVecTy); + + return CGF.Builder.CreateCall(F, {Rsrc, CGF.EmitScalarExpr(E->getArg(1)), + CGF.EmitScalarExpr(E->getArg(2))}); +} + // Has second type mangled argument. static Value * emitBinaryExpMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, const CallExpr *E, @@ -2154,6 +2170,30 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_raw_ptr_buffer_atomic_fmax_f64: return emitBuiltinWithOneOverloadedType<5>( *this, E, Intrinsic::amdgcn_raw_ptr_buffer_atomic_fmax); + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v8i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v16i32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v8f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v16f32: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_u8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_i16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_u16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4i8: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v2f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v3f16: + case AMDGPU::BI__builtin_amdgcn_s_buffer_load_v4f16: + return emitAMDGPUSBufferLoadBuiltin(*this, E); case AMDGPU::BI__builtin_amdgcn_s_prefetch_data: return emitBuiltinWithOneOverloadedType<2>( *this, E, Intrinsic::amdgcn_s_prefetch_data); diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl new file mode 100644 index 0000000000000..0c640e5020267 --- /dev/null +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-s-buffer-load.cl @@ -0,0 +1,286 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -emit-llvm -o - %s | FileCheck %s + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +typedef int v4i32 __attribute__((ext_vector_type(4))); +typedef int v2i32 __attribute__((ext_vector_type(2))); +typedef int v3i32 __attribute__((ext_vector_type(3))); +typedef int v8i32 __attribute__((ext_vector_type(8))); +typedef int v16i32 __attribute__((ext_vector_type(16))); +typedef float v2f32 __attribute__((ext_vector_type(2))); +typedef float v3f32 __attribute__((ext_vector_type(3))); +typedef float v4f32 __attribute__((ext_vector_type(4))); +typedef float v8f32 __attribute__((ext_vector_type(8))); +typedef float v16f32 __attribute__((ext_vector_type(16))); +typedef char v2i8 __attribute__((ext_vector_type(2))); +typedef char v3i8 __attribute__((ext_vector_type(3))); +typedef char v4i8 __attribute__((ext_vector_type(4))); +typedef half v2f16 __attribute__((ext_vector_type(2))); +typedef half v3f16 __attribute__((ext_vector_type(3))); +typedef half v4f16 __attribute__((ext_vector_type(4))); + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_amdgcn_s_buffer_load_i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i32_non_const_offset( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.amdgcn.s.buffer.load.i32(<4 x i32> [[RSRC_VEC:%.*]], i32 [[OFFSET:%.*]], i32 0) +// CHECK-NEXT: ret i32 [[TMP0]] +// +int test_amdgcn_s_buffer_load_i32_non_const_offset(__amdgpu_buffer_rsrc_t rsrc, int offset) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, offset, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.s.buffer.load.v2i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +v2i32 test_amdgcn_s_buffer_load_v2i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.s.buffer.load.v3i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x i32> [[TMP0]] +// +v3i32 test_amdgcn_s_buffer_load_v3i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i32> @llvm.amdgcn.s.buffer.load.v4i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +v4i32 test_amdgcn_s_buffer_load_v4i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v8i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x i32> @llvm.amdgcn.s.buffer.load.v8i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <8 x i32> [[TMP0]] +// +v8i32 test_amdgcn_s_buffer_load_v8i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v8i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v16i32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x i32> @llvm.amdgcn.s.buffer.load.v16i32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <16 x i32> [[TMP0]] +// +v16i32 test_amdgcn_s_buffer_load_v16i32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v16i32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call float @llvm.amdgcn.s.buffer.load.f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret float [[TMP0]] +// +float test_amdgcn_s_buffer_load_f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x float> @llvm.amdgcn.s.buffer.load.v2f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x float> [[TMP0]] +// +v2f32 test_amdgcn_s_buffer_load_v2f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x float> @llvm.amdgcn.s.buffer.load.v3f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x float> [[TMP0]] +// +v3f32 test_amdgcn_s_buffer_load_v3f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x float> @llvm.amdgcn.s.buffer.load.v4f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x float> [[TMP0]] +// +v4f32 test_amdgcn_s_buffer_load_v4f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v8f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <8 x float> @llvm.amdgcn.s.buffer.load.v8f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <8 x float> [[TMP0]] +// +v8f32 test_amdgcn_s_buffer_load_v8f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v8f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v16f32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <16 x float> @llvm.amdgcn.s.buffer.load.v16f32(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <16 x float> [[TMP0]] +// +v16f32 test_amdgcn_s_buffer_load_v16f32(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v16f32(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.s.buffer.load.i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +char test_amdgcn_s_buffer_load_i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_u8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i8 @llvm.amdgcn.s.buffer.load.i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i8 [[TMP0]] +// +unsigned char test_amdgcn_s_buffer_load_u8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_u8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_i16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.s.buffer.load.i16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +short test_amdgcn_s_buffer_load_i16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_u16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call i16 @llvm.amdgcn.s.buffer.load.i16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret i16 [[TMP0]] +// +unsigned short test_amdgcn_s_buffer_load_u16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_u16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call half @llvm.amdgcn.s.buffer.load.f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret half [[TMP0]] +// +half test_amdgcn_s_buffer_load_f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x half> @llvm.amdgcn.s.buffer.load.v2f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x half> [[TMP0]] +// +v2f16 test_amdgcn_s_buffer_load_v2f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x half> @llvm.amdgcn.s.buffer.load.v3f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x half> [[TMP0]] +// +v3f16 test_amdgcn_s_buffer_load_v3f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4f16( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x half> @llvm.amdgcn.s.buffer.load.v4f16(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x half> [[TMP0]] +// +v4f16 test_amdgcn_s_buffer_load_v4f16(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4f16(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v2i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <2 x i8> @llvm.amdgcn.s.buffer.load.v2i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <2 x i8> [[TMP0]] +// +v2i8 test_amdgcn_s_buffer_load_v2i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v2i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v3i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <3 x i8> @llvm.amdgcn.s.buffer.load.v3i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <3 x i8> [[TMP0]] +// +v3i8 test_amdgcn_s_buffer_load_v3i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v3i8(rsrc, /*offset=*/0, /*aux=*/0); +} + +// CHECK-LABEL: @test_amdgcn_s_buffer_load_v4i8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[RSRC_INT:%.*]] = ptrtoint ptr addrspace(8) [[RSRC:%.*]] to i128 +// CHECK-NEXT: [[RSRC_VEC:%.*]] = bitcast i128 [[RSRC_INT]] to <4 x i32> +// CHECK-NEXT: [[TMP0:%.*]] = tail call <4 x i8> @llvm.amdgcn.s.buffer.load.v4i8(<4 x i32> [[RSRC_VEC:%.*]], i32 0, i32 0) +// CHECK-NEXT: ret <4 x i8> [[TMP0]] +// +v4i8 test_amdgcn_s_buffer_load_v4i8(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_v4i8(rsrc, /*offset=*/0, /*aux=*/0); +} diff --git a/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl b/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl new file mode 100644 index 0000000000000..3c1694aa54500 --- /dev/null +++ b/clang/test/SemaOpenCL/builtins-amdgcn-s-buffer-load-error.cl @@ -0,0 +1,125 @@ +// RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu verde -S -verify -o - %s +// REQUIRES: amdgpu-registered-target + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +typedef int v4i32 __attribute__((ext_vector_type(4))); +typedef int v2i32 __attribute__((ext_vector_type(2))); +typedef int v3i32 __attribute__((ext_vector_type(3))); +typedef int v8i32 __attribute__((ext_vector_type(8))); +typedef int v16i32 __attribute__((ext_vector_type(16))); +typedef float v2f32 __attribute__((ext_vector_type(2))); +typedef float v3f32 __attribute__((ext_vector_type(3))); +typedef float v4f32 __attribute__((ext_vector_type(4))); +typedef float v8f32 __attribute__((ext_vector_type(8))); +typedef float v16f32 __attribute__((ext_vector_type(16))); +typedef char v2i8 __attribute__((ext_vector_type(2))); +typedef char v3i8 __attribute__((ext_vector_type(3))); +typedef char v4i8 __attribute__((ext_vector_type(4))); +typedef half v2f16 __attribute__((ext_vector_type(2))); +typedef half v3f16 __attribute__((ext_vector_type(3))); +typedef half v4f16 __attribute__((ext_vector_type(4))); + +int test_amdgcn_s_buffer_load_i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i32' must be a constant integer}} +} + +v2i32 test_amdgcn_s_buffer_load_v2i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2i32' must be a constant integer}} +} + +v3i32 test_amdgcn_s_buffer_load_v3i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3i32' must be a constant integer}} +} + +v4i32 test_amdgcn_s_buffer_load_v4i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4i32' must be a constant integer}} +} + +v8i32 test_amdgcn_s_buffer_load_v8i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v8i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v8i32' must be a constant integer}} +} + +v16i32 test_amdgcn_s_buffer_load_v16i32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v16i32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v16i32' must be a constant integer}} +} + +float test_amdgcn_s_buffer_load_f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_f32' must be a constant integer}} +} + +v2f32 test_amdgcn_s_buffer_load_v2f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2f32' must be a constant integer}} +} + +v3f32 test_amdgcn_s_buffer_load_v3f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3f32' must be a constant integer}} +} + +v4f32 test_amdgcn_s_buffer_load_v4f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4f32' must be a constant integer}} +} + +v8f32 test_amdgcn_s_buffer_load_v8f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v8f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v8f32' must be a constant integer}} +} + +v16f32 test_amdgcn_s_buffer_load_v16f32_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v16f32(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v16f32' must be a constant integer}} +} + +char test_amdgcn_s_buffer_load_i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i8' must be a constant integer}} +} + +unsigned char test_amdgcn_s_buffer_load_u8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_u8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_u8' must be a constant integer}} +} + +short test_amdgcn_s_buffer_load_i16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_i16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_i16' must be a constant integer}} +} + +unsigned short test_amdgcn_s_buffer_load_u16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_u16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_u16' must be a constant integer}} +} + +v2i8 test_amdgcn_s_buffer_load_v2i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2i8' must be a constant integer}} +} + +v3i8 test_amdgcn_s_buffer_load_v3i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3i8' must be a constant integer}} +} + +v4i8 test_amdgcn_s_buffer_load_v4i8_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4i8(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4i8' must be a constant integer}} +} + +half test_amdgcn_s_buffer_load_f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_f16' must be a constant integer}} +} + +v2f16 test_amdgcn_s_buffer_load_v2f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v2f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v2f16' must be a constant integer}} +} + +v3f16 test_amdgcn_s_buffer_load_v3f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v3f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v3f16' must be a constant integer}} +} + +v4f16 test_amdgcn_s_buffer_load_v4f16_non_const_aux(__amdgpu_buffer_rsrc_t rsrc, int offset, int aux) { + return __builtin_amdgcn_s_buffer_load_v4f16(rsrc, offset, aux); //expected-error{{argument to '__builtin_amdgcn_s_buffer_load_v4f16' must be a constant integer}} +} + +int test_amdgcn_s_buffer_load_i32_too_few_args(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0); //expected-error{{too few arguments to function call, expected 3, have 2}} +} + +int test_amdgcn_s_buffer_load_i32_too_many_args(__amdgpu_buffer_rsrc_t rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0, 0, 0); //expected-error{{too many arguments to function call, expected 3, have 4}} +} + +int test_amdgcn_s_buffer_load_i32_wrong_rsrc_type(v4i32 rsrc) { + return __builtin_amdgcn_s_buffer_load_i32(rsrc, 0, 0); //expected-error{{passing '__private v4i32' (vector of 4 'int' values) to parameter of incompatible type '__amdgpu_buffer_rsrc_t'}} +} From 27d83e2795e7ae9f98f695fe5113493a83f46b28 Mon Sep 17 00:00:00 2001 From: Wael Yehia Date: Thu, 9 Jul 2026 19:29:40 -0400 Subject: [PATCH 047/125] [AIX] diagnose invalid feature strings on the target attribute (#208059) Currently, Sema calls `getTargetInfo().isValidFeatureName(S)` to validate string inputs on the `target` attribute. `PPCTargetInfo` doesn't override the function and the base class implementation returns true unconditionally. This results in the FE accepting invalid feature strings on `target` attribute, and generates invalid target-feature values in the IR. Co-authored-by: Wael Yehia --- clang/lib/Basic/Targets/PPC.cpp | 8 ++++++++ clang/lib/Basic/Targets/PPC.h | 2 ++ clang/test/Sema/attr-target.c | 4 ++-- llvm/include/llvm/TargetParser/PPCTargetParser.h | 1 + llvm/include/llvm/TargetParser/TargetParser.h | 3 +++ llvm/lib/TargetParser/PPCTargetParser.cpp | 7 +++++++ 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index c9a41df806aff..1ecb474c1ede8 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -714,6 +714,14 @@ ParsedTargetAttr PPCTargetInfo::parseTargetAttr(StringRef Features) const { return Ret; } +bool PPCTargetInfo::isValidFeatureName(StringRef Name) const { + // we have some target features that are spelled differently on the command + // line versus what's in PPC.td. We need to continue accepting them. + if (Name == "pcrel" || Name == "prefixed") + return true; + return llvm::PPC::isValidFeatureName(Name); +} + llvm::APInt PPCTargetInfo::getFMVPriority(ArrayRef Features) const { if (Features.empty()) return llvm::APInt(32, 0); diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index e3bf5072d932d..22880e5a04a3f 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -202,6 +202,8 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + bool isValidFeatureName(StringRef Name) const override; + llvm::APInt getFMVPriority(ArrayRef Features) const override; ArrayRef getGCCRegNames() const override; diff --git a/clang/test/Sema/attr-target.c b/clang/test/Sema/attr-target.c index 036cfc5f53c64..6e9d85b5e1d67 100644 --- a/clang/test/Sema/attr-target.c +++ b/clang/test/Sema/attr-target.c @@ -67,7 +67,7 @@ int __attribute__((target("branch-protection=none"))) birch_tree(void) { return #elifdef __powerpc__ -int __attribute__((target("float128,arch=pwr9"))) foo(void) { return 4; } +int __attribute__((target("float128,cpu=pwr9"))) foo(void) { return 4; } //expected-error@+1 {{'target' attribute takes one argument}} int __attribute__((target())) bar(void) { return 4; } // no warning, tune is supported for PPC @@ -84,7 +84,7 @@ int __attribute__((target("cpu=hiss,cpu=woof"))) pine_tree(void) { return 4; } int __attribute__((target("cpu=pwr9,cpu=pwr10"))) oak_tree(void) { return 4; } //expected-warning@+1 {{unknown tune CPU 'hiss' in the 'target' attribute string; 'target' attribute ignored}} int __attribute__((target("tune=hiss,tune=woof"))) apple_tree(void) { return 4; } -// no warning for invalid target features +//expected-warning@+1 {{unsupported 'woof' in the 'target' attribute string; 'target' attribute ignored}} int __attribute__((target("woof"))) cherry_tree(void) { return 4; } #else diff --git a/llvm/include/llvm/TargetParser/PPCTargetParser.h b/llvm/include/llvm/TargetParser/PPCTargetParser.h index d3d44afb5f544..9f39551377f70 100644 --- a/llvm/include/llvm/TargetParser/PPCTargetParser.h +++ b/llvm/include/llvm/TargetParser/PPCTargetParser.h @@ -43,6 +43,7 @@ LLVM_ABI StringRef normalizeCPUName(StringRef CPUName); LLVM_ABI std::optional> getPPCDefaultTargetFeatures(const Triple &T, StringRef CPUName); +LLVM_ABI bool isValidFeatureName(StringRef Name); } // namespace PPC } // namespace llvm diff --git a/llvm/include/llvm/TargetParser/TargetParser.h b/llvm/include/llvm/TargetParser/TargetParser.h index b65ff37dfc958..2346c5f407219 100644 --- a/llvm/include/llvm/TargetParser/TargetParser.h +++ b/llvm/include/llvm/TargetParser/TargetParser.h @@ -27,6 +27,9 @@ struct BasicSubtargetFeatureKV { const char *Key; ///< K-V key string unsigned Value; ///< K-V integer value FeatureBitArray Implies; ///< K-V bit mask + + /// Compare routine for std::lower_bound + bool operator<(StringRef S) const { return StringRef(Key) < S; } }; /// Used to provide key value pairs for feature and CPU bit flags. diff --git a/llvm/lib/TargetParser/PPCTargetParser.cpp b/llvm/lib/TargetParser/PPCTargetParser.cpp index 106d07107ac8c..76c2c13ac53a4 100644 --- a/llvm/lib/TargetParser/PPCTargetParser.cpp +++ b/llvm/lib/TargetParser/PPCTargetParser.cpp @@ -145,5 +145,12 @@ std::optional> getPPCDefaultTargetFeatures(const Triple &T, } return Features; } + +bool isValidFeatureName(StringRef Name) { + ArrayRef A = BasicPPCFeatureKV; + // Binary search the array + const BasicSubtargetFeatureKV *F = llvm::lower_bound(A, Name); + return F != A.end() && StringRef(F->Key) == Name; +} } // namespace PPC } // namespace llvm From 880f3d0fbe323abfe225193254244c8163d40712 Mon Sep 17 00:00:00 2001 From: Jianhui Li Date: Thu, 9 Jul 2026 16:33:01 -0700 Subject: [PATCH 048/125] [mlir][xegpu] Support subgroup layout assignment for scatter stores (#205955) Add getStoreSubgroupLayouts() to derive the subgroup (sg_layout/sg_data) anchor layout for store_scatter and store_matrix. It factorizes numSg into the most balanced sg_layout that divides the workgroup tile with sg_data a multiple of inst_data (lane_layout * lane_data). Co-authored-by: Claude Opus 4.8 (1M context) --- .../XeGPU/Transforms/XeGPULayoutImpl.h | 4 ++ .../XeGPU/Transforms/XeGPULayoutImpl.cpp | 57 +++++++++++-------- .../XeGPU/Transforms/XeGPUPropagateLayout.cpp | 26 ++++++++- .../XeGPU/propagate-layout-subgroup.mlir | 47 +++++++++++++++ 4 files changed, 107 insertions(+), 27 deletions(-) diff --git a/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h b/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h index 5f313e480c918..75fcb156a9d0d 100644 --- a/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h +++ b/mlir/include/mlir/Dialect/XeGPU/Transforms/XeGPULayoutImpl.h @@ -234,15 +234,19 @@ DistributeLayoutAttr setupLoadMatrixAnchorLayout( DistributeLayoutAttr consumerLayout, const uArch::uArch *uArch); /// Sets up the anchor layout for a store scatter operation. +/// `numSg` is only used for Subgroup-kind layouts. DistributeLayoutAttr setupStoreScatterAnchorLayout(LayoutKind layoutKind, VectorType vectorTy, int contigChunkSize, + int numSg, const uArch::uArch *uArch); /// Sets up the anchor layout for a store matrix operation. +/// `numSg` is only used for Subgroup-kind layouts. DistributeLayoutAttr setupStoreMatrixAnchorLayout(LayoutKind layoutKind, VectorType vectorTy, int contigChunkSize, + int numSg, const uArch::uArch *uArch); /// If the consumer layout has only inst_data (no lane_layout/lane_data), diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp index 6ea55f4c78dd6..8da151a333fb3 100644 --- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp +++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPULayoutImpl.cpp @@ -1752,31 +1752,39 @@ xegpu::setupLoadMatrixAnchorLayout(xegpu::LayoutKind layoutKind, maxChunkSize, resShape, subgroupSize); } -/// Sets up the anchor layout for store scatter and store matrix operation. -/// store matrix lowers to store scatter and 1d block store. All of them -/// share the same layout setup logic. For Subgroup layout, not supported -/// yet. -/// -/// Lane layout is derived first via `computeScatterIOLaneLayoutAndData`; -/// inst_data is then the element-wise product lane_layout * lane_data. +/// Picks the subgroup layout for a scatter-style store (store_scatter / +/// store_matrix): the most balanced `numSg` factorization that divides +/// `wgShape` with sg_data a multiple of `instData`. A store has no consumer. static xegpu::DistributeLayoutAttr -setupGenericStoreAnchorLayout(xegpu::LayoutKind layoutKind, - mlir::MLIRContext *context, int maxChunkSize, - ArrayRef srcShape, int subgroupSize) { - - if (layoutKind == xegpu::LayoutKind::Subgroup) { - assert(false && - "subgroup layout assignment not supported for storeScatter."); +getStoreSubgroupLayouts(mlir::MLIRContext *context, ArrayRef wgShape, + ArrayRef instData, int numSg) { + auto candidates = getSgLayoutCandidates(wgShape, instData, numSg); + if (candidates.empty()) return nullptr; - } + // Candidates are ordered most-balanced first. + return buildSgLayout(context, wgShape, candidates.front(), /*dimK=*/-1); +} + +/// Sets up the anchor layout for store scatter and store matrix operation, +/// which share the same logic. Lane layout comes from +/// `computeScatterIOLaneLayoutAndData`; inst_data is lane_layout * lane_data. +static xegpu::DistributeLayoutAttr setupGenericStoreAnchorLayout( + xegpu::LayoutKind layoutKind, mlir::MLIRContext *context, int maxChunkSize, + ArrayRef srcShape, int subgroupSize, int numSg) { auto [laneLayout, laneData] = computeScatterIOLaneLayoutAndData(srcShape, subgroupSize, maxChunkSize); + SmallVector instData(srcShape.size()); + for (size_t i = 0; i < srcShape.size(); ++i) + instData[i] = laneLayout[i] * laneData[i]; + + if (layoutKind == xegpu::LayoutKind::Subgroup) { + assert(numSg > 0 && + "Number of subgroups must be provided for sg layout creation."); + return getStoreSubgroupLayouts(context, srcShape, instData, numSg); + } if (layoutKind == xegpu::LayoutKind::InstData) { - SmallVector instData(srcShape.size()); - for (size_t i = 0; i < srcShape.size(); ++i) - instData[i] = laneLayout[i] * laneData[i]; return buildInstDataLayoutWithLane(context, instData, laneLayout, laneData); } if (layoutKind == xegpu::LayoutKind::Lane) { @@ -1789,7 +1797,7 @@ setupGenericStoreAnchorLayout(xegpu::LayoutKind layoutKind, xegpu::DistributeLayoutAttr xegpu::setupStoreScatterAnchorLayout(xegpu::LayoutKind layoutKind, VectorType srcVecTy, int contigChunkSize, - const uArch::uArch *uArch) { + int numSg, const uArch::uArch *uArch) { const int subgroupSize = uArch->getSubgroupSize(); ArrayRef srcShape = srcVecTy.getShape(); @@ -1801,14 +1809,13 @@ xegpu::setupStoreScatterAnchorLayout(xegpu::LayoutKind layoutKind, int maxChunkSize = std::min(uArchInstruction->getMaxLaneAccessSizeBytes(), contigChunkSize); return setupGenericStoreAnchorLayout(layoutKind, context, maxChunkSize, - srcShape, subgroupSize); + srcShape, subgroupSize, numSg); } /// Sets up the anchor layout for a store matrix operation. -xegpu::DistributeLayoutAttr -xegpu::setupStoreMatrixAnchorLayout(xegpu::LayoutKind layoutKind, - VectorType srcVecTy, int contigChunkSize, - const xegpu::uArch::uArch *uArch) { +xegpu::DistributeLayoutAttr xegpu::setupStoreMatrixAnchorLayout( + xegpu::LayoutKind layoutKind, VectorType srcVecTy, int contigChunkSize, + int numSg, const xegpu::uArch::uArch *uArch) { const int subgroupSize = uArch->getSubgroupSize(); ArrayRef srcShape = srcVecTy.getShape(); @@ -1821,7 +1828,7 @@ xegpu::setupStoreMatrixAnchorLayout(xegpu::LayoutKind layoutKind, std::min(uArchInstruction->getMaxLaneAccessSizeBytes(), contigChunkSize); return setupGenericStoreAnchorLayout(layoutKind, context, maxChunkSize, - srcShape, subgroupSize); + srcShape, subgroupSize, numSg); } /// Completes a scatter IO layout by deriving lane_layout and lane_data from diff --git a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp index 64d0d8063b7ff..1b1abcc4b0e4f 100644 --- a/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp +++ b/mlir/lib/Dialect/XeGPU/Transforms/XeGPUPropagateLayout.cpp @@ -1273,8 +1273,19 @@ void LayoutInfoPropagation::visitStoreScatterOp( storeScatter.emitWarning("Not propagating, non-vector payload supplied."); return; } + auto numSgOrErr = getNumSg(storeScatter, uArch->getSubgroupSize()); + if (layoutKind == xegpu::LayoutKind::Subgroup && failed(numSgOrErr)) { + storeScatter.emitWarning( + "Unable to determine the number of subgroups for the operation."); + return; + } requiredAnchorLayoutAttr = xegpu::setupStoreScatterAnchorLayout( - layoutKind, srcVecTy, chunkSize, uArch); + layoutKind, srcVecTy, chunkSize, numSgOrErr.value_or(0), uArch); + if (!requiredAnchorLayoutAttr) { + storeScatter.emitWarning( + "Failed to determine required layout for store scatter."); + return; + } storeScatter.setLayoutAttr(requiredAnchorLayoutAttr); } @@ -1357,8 +1368,19 @@ void LayoutInfoPropagation::visitStoreMatrixOp( } else { int chunkSize = 1; // placeHolder for future use when StoreMatrix supports coalescing + auto numSgOrErr = getNumSg(storeMatrix, uArch->getSubgroupSize()); + if (layoutKind == xegpu::LayoutKind::Subgroup && failed(numSgOrErr)) { + storeMatrix.emitWarning( + "Unable to determine the number of subgroups for the operation."); + return; + } requiredAnchorLayoutAttr = xegpu::setupStoreMatrixAnchorLayout( - layoutKind, srcVecTy, chunkSize, uArch); + layoutKind, srcVecTy, chunkSize, numSgOrErr.value_or(0), uArch); + if (!requiredAnchorLayoutAttr) { + storeMatrix.emitWarning( + "Failed to determine required layout for store matrix."); + return; + } storeMatrix.setLayoutAttr(requiredAnchorLayoutAttr); } layout = LayoutInfo(requiredAnchorLayoutAttr); diff --git a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir index 000f6c1cc916d..fa00c1d894d8f 100644 --- a/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir +++ b/mlir/test/Dialect/XeGPU/propagate-layout-subgroup.mlir @@ -607,6 +607,53 @@ gpu.module @test { } } +// ----- +gpu.module @test { + // Self-derived sg layout: 256 threads / 16 = 16 subgroups, sg_data = 16. + // CHECK-LABEL: store_scatter + gpu.func @store_scatter(%dest: memref<256xf16>) kernel attributes {known_block_size = array} { + %val = arith.constant dense<25.5> : vector<256xf16> + %offset = arith.constant dense<0> : vector<256xindex> + %mask = arith.constant dense<1> : vector<256xi1> + // CHECK: xegpu.store %{{.*}}, %{{.*}}[%{{.*}}], %{{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint, layout = #xegpu.layout}> + // CHECK-SAME: : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + xegpu.store %val, %dest[%offset], %mask {chunk_size = 1, l1_hint = #xegpu.cache_hint} + : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + gpu.return + } +} + +// ----- +gpu.module @test { + // Self-derived sg layout: 512 threads / 16 = 32 subgroups, most balanced + // factorization [4, 8] over [64, 128] -> sg_data [16, 16]. + // CHECK-LABEL: store_matrix + gpu.func @store_matrix(%mem: !xegpu.mem_desc<64x128xf16>, %val: vector<64x128xf16>) kernel attributes {known_block_size = array} { + %c0 = arith.constant 0 : index + // CHECK: xegpu.store_matrix %{{.*}}, %{{.*}}[%{{.*}}, %{{.*}}] <{layout = #xegpu.layout}> + // CHECK-SAME: : vector<64x128xf16>, !xegpu.mem_desc<64x128xf16>, index, index + xegpu.store_matrix %val, %mem[%c0, %c0] : vector<64x128xf16>, !xegpu.mem_desc<64x128xf16>, index, index + gpu.return + } +} + +// ----- +gpu.module @test { + // No valid sg layout: 32 subgroups over 256 elements forces sg_data = 8 < + // 16-lane tile, so every candidate is rejected; layout is left unassigned. + // CHECK-LABEL: store_scatter_no_valid_sg_layout + gpu.func @store_scatter_no_valid_sg_layout(%dest: memref<256xf16>) kernel attributes {known_block_size = array} { + %val = arith.constant dense<25.5> : vector<256xf16> + %offset = arith.constant dense<0> : vector<256xindex> + %mask = arith.constant dense<1> : vector<256xi1> + // CHECK: xegpu.store %{{.*}}, %{{.*}}[%{{.*}}], %{{.*}} <{chunk_size = 1 : i64, l1_hint = #xegpu.cache_hint}> + // CHECK-SAME: : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + xegpu.store %val, %dest[%offset], %mask {chunk_size = 1, l1_hint = #xegpu.cache_hint} + : vector<256xf16>, memref<256xf16>, vector<256xindex>, vector<256xi1> + gpu.return + } +} + // ----- gpu.module @test { // CHECK-LABEL: gpu.func @transpose_3d_order_remap( From b2b67ba3b96d33b5ab71c1ad7f1e529b61f41883 Mon Sep 17 00:00:00 2001 From: Shilei Tian Date: Thu, 9 Jul 2026 19:42:53 -0400 Subject: [PATCH 049/125] [GISel] Don't return false when an intrinsic is not supported (#208567) This will abort immediately by default, which is not ideal. --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 -- llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 97e64230b73d9..c66226258c87e 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -2882,7 +2882,6 @@ bool IRTranslator::translateCall(const User &U, MachineIRBuilder &MIRBuilder) { const Function &Fn = MF->getFunction(); Fn.getContext().diagnose( DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.getDebugLoc())); - return false; } if (translateKnownIntrinsic(CI, ID, MIRBuilder)) @@ -2902,7 +2901,6 @@ bool IRTranslator::translateIntrinsic( const Function &F = MF->getFunction(); F.getContext().diagnose( DiagnosticInfoUnsupportedTargetIntrinsic(F, ID, CB.getDebugLoc())); - return false; } ArrayRef ResultRegs; diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll index 68a6ab1d4d4f9..578bbf830344a 100644 --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.permlane16.swap.ll @@ -5,7 +5,7 @@ ; RUN: llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1250 < %s | FileCheck -check-prefix=GFX1250 %s ; RUN: not llc -global-isel=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s -; RUN: not llc -global-isel=1 -global-isel-abort=0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s +; RUN: not llc -global-isel=1 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx942 -filetype=null %s 2>&1 | FileCheck -check-prefix=ERR %s ; ERR: error: {{.*}}: in function {{@?}}v_permlane16_swap_b32_vv{{.*}}: llvm.amdgcn.permlane16.swap requires target feature 'permlane16-swap' From f5169f2a5c53ef64c751ccbafa1799f9915b2814 Mon Sep 17 00:00:00 2001 From: halbi2 Date: Thu, 9 Jul 2026 19:46:26 -0400 Subject: [PATCH 050/125] [libc++] Enable missing allocator constructors in C++11 (#204845) LWG2210 was a patch to N2554 (C++11) which added missing allocator-extended constructors to various containers. When LWG2210 was implemented, the constructors were gated with C++14. However, we normally apply LWG issue resolutions as DRs. This patch enables these constructors in C++11 mode too. Fixes #204843 --------- Co-authored-by: Louis Dionne Co-authored-by: A. Jiang --- libcxx/include/__vector/vector.h | 2 - libcxx/include/__vector/vector_bool.h | 4 -- libcxx/include/deque | 6 +-- libcxx/include/forward_list | 6 +-- libcxx/include/list | 10 ++--- libcxx/include/map | 20 +++------- libcxx/include/set | 24 ++++------- libcxx/include/unordered_map | 36 ++++++++--------- libcxx/include/unordered_set | 36 ++++++----------- libcxx/include/vector | 4 +- .../map.cons/iter_iter_comp_alloc.pass.cpp | 2 - .../iter_iter_comp_alloc.pass.cpp | 40 +++++++++++++++++++ .../multiset.cons/iter_iter_alloc.pass.cpp | 2 +- .../set/set.cons/iter_iter_alloc.pass.cpp | 2 +- .../sequences/deque/deque.cons/size.pass.cpp | 7 ++-- .../forwardlist.cons/size.pass.cpp | 25 +++++++----- .../list/list.cons/size_type.pass.cpp | 24 +++++++---- .../vector.bool/construct_size.pass.cpp | 3 +- .../vector.cons/construct_size.pass.cpp | 2 +- .../init_size_allocator.pass.cpp | 2 +- .../init_size_hash_allocator.pass.cpp | 2 +- .../iter_iter_size_allocator.pass.cpp | 2 +- .../iter_iter_size_hash_allocator.pass.cpp | 2 +- .../unord.map.cnstr/size_allocator.pass.cpp | 2 +- .../size_hash_allocator.pass.cpp | 2 +- .../init_size_allocator.pass.cpp | 2 +- .../init_size_hash_allocator.pass.cpp | 2 +- .../iter_iter_size_allocator.pass.cpp | 2 +- .../iter_iter_size_hash_allocator.pass.cpp | 2 +- .../size_allocator.pass.cpp | 2 +- .../size_hash_allocator.pass.cpp | 2 +- .../init_size_allocator.pass.cpp | 2 +- .../init_size_hash_allocator.pass.cpp | 2 +- .../iter_iter_size_allocator.pass.cpp | 2 +- .../iter_iter_size_hash_allocator.pass.cpp | 2 +- .../size_allocator.pass.cpp | 2 +- .../size_hash_allocator.pass.cpp | 2 +- .../init_size_allocator.pass.cpp | 2 +- .../init_size_hash_allocator.pass.cpp | 2 +- .../iter_iter_size_allocator.pass.cpp | 2 +- .../iter_iter_size_hash_allocator.pass.cpp | 2 +- .../unord.set.cnstr/size_allocator.pass.cpp | 2 +- .../size_hash_allocator.pass.cpp | 2 +- 43 files changed, 159 insertions(+), 144 deletions(-) diff --git a/libcxx/include/__vector/vector.h b/libcxx/include/__vector/vector.h index 422c98c300a1d..8226a7f87a119 100644 --- a/libcxx/include/__vector/vector.h +++ b/libcxx/include/__vector/vector.h @@ -153,7 +153,6 @@ class vector { __guard.__complete(); } -#if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit vector(size_type __n, const allocator_type& __a) : __layout_(__a) { auto __guard = std::__make_exception_guard(__destroy_vector(*this)); @@ -163,7 +162,6 @@ class vector { } __guard.__complete(); } -#endif _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI vector(size_type __n, const value_type& __x) { auto __guard = std::__make_exception_guard(__destroy_vector(*this)); diff --git a/libcxx/include/__vector/vector_bool.h b/libcxx/include/__vector/vector_bool.h index f73e086478a70..6dc904e6d3bd9 100644 --- a/libcxx/include/__vector/vector_bool.h +++ b/libcxx/include/__vector/vector_bool.h @@ -152,9 +152,7 @@ class vector { _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 ~vector() { __destroy_vector (*this)(); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n); -#if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 explicit vector(size_type __n, const allocator_type& __a); -#endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v); _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 vector(size_type __n, const value_type& __v, const allocator_type& __a); @@ -605,7 +603,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n) } } -#if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, const allocator_type& __a) : __begin_(nullptr), __size_(0), __cap_(0), __alloc_(static_cast<__storage_allocator>(__a)) { @@ -615,7 +612,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, co __size_ = __n; } } -#endif template _LIBCPP_CONSTEXPR_SINCE_CXX20 vector::vector(size_type __n, const value_type& __x) diff --git a/libcxx/include/deque b/libcxx/include/deque index 7aee552c63d37..5a4de99c7f143 100644 --- a/libcxx/include/deque +++ b/libcxx/include/deque @@ -40,7 +40,7 @@ public: deque() noexcept(is_nothrow_default_constructible::value); explicit deque(const allocator_type& a); explicit deque(size_type n); - explicit deque(size_type n, const allocator_type& a); // C++14 + explicit deque(size_type n, const allocator_type& a); deque(size_type n, const value_type& v); deque(size_type n, const value_type& v, const allocator_type& a); template @@ -644,9 +644,7 @@ public: } explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n); -# if _LIBCPP_STD_VER >= 14 explicit _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const _Allocator& __a); -# endif _LIBCPP_HIDE_FROM_ABI deque(size_type __n, const value_type& __v); template <__enable_if_t<__is_allocator_v<_Allocator>, int> = 0> @@ -1323,7 +1321,6 @@ deque<_Tp, _Allocator>::deque(size_type __n) : __start_(0), __size_(0) { __append(__n); } -# if _LIBCPP_STD_VER >= 14 template deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) : __map_(__pointer_allocator(__a)), __start_(0), __size_(0), __alloc_(__a) { @@ -1331,7 +1328,6 @@ deque<_Tp, _Allocator>::deque(size_type __n, const _Allocator& __a) if (__n > 0) __append(__n); } -# endif template deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v) : __start_(0), __size_(0) { diff --git a/libcxx/include/forward_list b/libcxx/include/forward_list index 6d86f7a8e5975..d963fea6084ca 100644 --- a/libcxx/include/forward_list +++ b/libcxx/include/forward_list @@ -37,7 +37,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit forward_list(const allocator_type& a); explicit forward_list(size_type n); - explicit forward_list(size_type n, const allocator_type& a); // C++14 + explicit forward_list(size_type n, const allocator_type& a); forward_list(size_type n, const value_type& v); forward_list(size_type n, const value_type& v, const allocator_type& a); template @@ -664,9 +664,7 @@ public: _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} // = default; _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(const allocator_type& __a); _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n); -# if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit forward_list(size_type __n, const allocator_type& __a); -# endif _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI forward_list(size_type __n, const value_type& __v); template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0> @@ -941,7 +939,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type } } -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const allocator_type& __base_alloc) : __base(__base_alloc) { @@ -952,7 +949,6 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type } } } -# endif template _LIBCPP_CONSTEXPR_SINCE_CXX26 forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v) { diff --git a/libcxx/include/list b/libcxx/include/list index 3223f25e1cfba..b4fb9191cd7f7 100644 --- a/libcxx/include/list +++ b/libcxx/include/list @@ -39,7 +39,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit list(const allocator_type& a); explicit list(size_type n); - explicit list(size_type n, const allocator_type& a); // C++14 + explicit list(size_type n, const allocator_type& a); list(size_type n, const value_type& value); list(size_type n, const value_type& value, const allocator_type& a); template @@ -708,9 +708,7 @@ public: _NOEXCEPT_(is_nothrow_default_constructible<__node_allocator>::value) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(const allocator_type& __a) : __base(__a) {} _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n); -# if _LIBCPP_STD_VER >= 14 _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI explicit list(size_type __n, const allocator_type& __a); -# endif _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI list(size_type __n, const value_type& __x); template <__enable_if_t<__is_allocator_v<_Alloc>, int> = 0> _LIBCPP_CONSTEXPR_SINCE_CXX26 _LIBCPP_HIDE_FROM_ABI @@ -1066,13 +1064,15 @@ _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n) { # endif } -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const allocator_type& __a) : __base(__a) { for (; __n > 0; --__n) +# ifndef _LIBCPP_CXX03_LANG emplace_back(); -} +# else + push_back(value_type()); # endif +} template _LIBCPP_CONSTEXPR_SINCE_CXX26 list<_Tp, _Alloc>::list(size_type __n, const value_type& __x) { diff --git a/libcxx/include/map b/libcxx/include/map index 8efe18fa3f839..d51daa128eada 100644 --- a/libcxx/include/map +++ b/libcxx/include/map @@ -84,12 +84,12 @@ public: constexpr map(initializer_list il, const key_compare& comp, const allocator_type& a); template constexpr map(InputIterator first, InputIterator last, const allocator_type& a) - : map(first, last, Compare(), a) {} // C++14 + : map(first, last, Compare(), a) {} template R> constexpr map(from_range_t, R&& rg, const Allocator& a)) : map(from_range, std::forward(rg), Compare(), a) { } // C++23 constexpr map(initializer_list il, const allocator_type& a) - : map(il, Compare(), a) {} // C++14 + : map(il, Compare(), a) {} constexpr ~map(); constexpr map& operator=(const map& m); @@ -368,12 +368,12 @@ public: const allocator_type& a); template multimap(InputIterator first, InputIterator last, const allocator_type& a) - : multimap(first, last, Compare(), a) {} // C++14 + : multimap(first, last, Compare(), a) {} template R> multimap(from_range_t, R&& rg, const Allocator& a)) : multimap(from_range, std::forward(rg), Compare(), a) { } // C++23 multimap(initializer_list il, const allocator_type& a) - : multimap(il, Compare(), a) {} // C++14 + : multimap(il, Compare(), a) {} ~multimap(); multimap& operator=(const multimap& m); @@ -1035,12 +1035,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : map(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1073,10 +1071,8 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map(initializer_list __il, const allocator_type& __a) : map(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 map& operator=(initializer_list __il) { clear(); @@ -1817,12 +1813,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multimap(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1856,11 +1850,9 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap(initializer_list __il, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multimap(initializer_list __il, const allocator_type& __a) : multimap(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multimap& operator=(initializer_list __il) { clear(); diff --git a/libcxx/include/set b/libcxx/include/set index 0409131ac6981..59aef4a42b428 100644 --- a/libcxx/include/set +++ b/libcxx/include/set @@ -71,12 +71,12 @@ public: const allocator_type& a); template set(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 + : set(first, last, Compare(), a) {} template R> set(from_range_t, R&& rg, const Allocator& a)) : set(from_range, std::forward(rg), Compare(), a) { } // C++23 set(initializer_list il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 + : set(il, Compare(), a) {} ~set(); set& operator=(const set& s); @@ -316,12 +316,12 @@ public: const allocator_type& a); template multiset(InputIterator first, InputIterator last, const allocator_type& a) - : set(first, last, Compare(), a) {} // C++14 + : set(first, last, Compare(), a) {} template R> multiset(from_range_t, R&& rg, const Allocator& a)) : multiset(from_range, std::forward(rg), Compare(), a) { } // C++23 multiset(initializer_list il, const allocator_type& a) - : set(il, Compare(), a) {} // C++14 + : set(il, Compare(), a) {} ~multiset(); multiset& operator=(const multiset& s); @@ -653,12 +653,10 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : set(__f, __l, key_compare(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -695,10 +693,8 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set(initializer_list __il, const allocator_type& __a) : set(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 set& operator=(initializer_list __il) { clear(); @@ -1195,12 +1191,10 @@ public: insert(__f, __l); } -# if _LIBCPP_STD_VER >= 14 template - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multiset(_InputIterator __f, _InputIterator __l, const allocator_type& __a) : multiset(__f, __l, key_compare(), __a) {} -# endif template _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 @@ -1253,11 +1247,9 @@ public: insert(__il.begin(), __il.end()); } -# if _LIBCPP_STD_VER >= 14 - _LIBCPP_HIDE_FROM_ABI - _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset(initializer_list __il, const allocator_type& __a) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 + multiset(initializer_list __il, const allocator_type& __a) : multiset(__il, key_compare(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 multiset& operator=(initializer_list __il) { clear(); diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index 8cefba01fb5f6..b8b160cd892d4 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -77,16 +77,16 @@ public: const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_map(size_type n, const allocator_type& a) - : unordered_map(n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(n, hasher(), key_equal(), a) {} unordered_map(size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(n, hf, key_equal(), a) {} // C++14 + : unordered_map(n, hf, key_equal(), a) {} template unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_map(f, l, n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(f, l, n, hasher(), key_equal(), a) {} template unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(f, l, n, hf, key_equal(), a) {} // C++14 + : unordered_map(f, l, n, hf, key_equal(), a) {} template R> unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 @@ -94,10 +94,10 @@ public: unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 unordered_map(initializer_list il, size_type n, const allocator_type& a) - : unordered_map(il, n, hasher(), key_equal(), a) {} // C++14 + : unordered_map(il, n, hasher(), key_equal(), a) {} unordered_map(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) - : unordered_map(il, n, hf, key_equal(), a) {} // C++14 + : unordered_map(il, n, hf, key_equal(), a) {} ~unordered_map(); unordered_map& operator=(const unordered_map&); unordered_map& operator=(unordered_map&&) @@ -363,16 +363,16 @@ public: const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); unordered_multimap(size_type n, const allocator_type& a) - : unordered_multimap(n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(n, hasher(), key_equal(), a) {} unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(n, hf, key_equal(), a) {} template unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) - : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(f, l, n, hasher(), key_equal(), a) {} template unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(f, l, n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(f, l, n, hf, key_equal(), a) {} template R> unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 @@ -380,10 +380,10 @@ public: unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 unordered_multimap(initializer_list il, size_type n, const allocator_type& a) - : unordered_multimap(il, n, hasher(), key_equal(), a) {} // C++14 + : unordered_multimap(il, n, hasher(), key_equal(), a) {} unordered_multimap(initializer_list il, size_type n, const hasher& hf, const allocator_type& a) - : unordered_multimap(il, n, hf, key_equal(), a) {} // C++14 + : unordered_multimap(il, n, hf, key_equal(), a) {} ~unordered_multimap(); unordered_multimap& operator=(const unordered_multimap&); unordered_multimap& operator=(unordered_multimap&&) @@ -993,7 +993,6 @@ public: const key_equal& __eql, const allocator_type& __a); # endif // _LIBCPP_CXX03_LANG -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const allocator_type& __a) : unordered_map(__n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI unordered_map(size_type __n, const hasher& __hf, const allocator_type& __a) @@ -1007,7 +1006,7 @@ public: _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(__first, __last, __n, __hf, key_equal(), __a) {} -# if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> _LIBCPP_HIDE_FROM_ABI unordered_map(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) : unordered_map(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} @@ -1016,8 +1015,9 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_map(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_map(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} -# endif +# endif +# ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI unordered_map(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_map(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI @@ -1787,7 +1787,6 @@ public: const key_equal& __eql, const allocator_type& __a); # endif // _LIBCPP_CXX03_LANG -# if _LIBCPP_STD_VER >= 14 _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const allocator_type& __a) : unordered_multimap(__n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI unordered_multimap(size_type __n, const hasher& __hf, const allocator_type& __a) @@ -1801,7 +1800,7 @@ public: _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) {} -# if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> _LIBCPP_HIDE_FROM_ABI unordered_multimap(from_range_t, _Range&& __range, size_type __n, const allocator_type& __a) : unordered_multimap(from_range, std::forward<_Range>(__range), __n, hasher(), key_equal(), __a) {} @@ -1810,8 +1809,9 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_multimap(from_range_t, _Range&& __range, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multimap(from_range, std::forward<_Range>(__range), __n, __hf, key_equal(), __a) {} -# endif +# endif +# ifndef _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI unordered_multimap(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_multimap(__il, __n, hasher(), key_equal(), __a) {} _LIBCPP_HIDE_FROM_ABI diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index d54d59403b038..10f8b730b842b 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -76,22 +76,22 @@ public: unordered_set(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_set(size_type n, const allocator_type& a); // C++14 - unordered_set(size_type n, const hasher& hf, const allocator_type& a); // C++14 + unordered_set(size_type n, const allocator_type& a); + unordered_set(size_type n, const hasher& hf, const allocator_type& a); template - unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 + unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); template unordered_set(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); template R> unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 template R> unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_set(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 - unordered_set(initializer_list il, size_type n, const allocator_type& a); // C++14 + unordered_set(initializer_list il, size_type n, const allocator_type& a); unordered_set(initializer_list il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); ~unordered_set(); unordered_set& operator=(const unordered_set&); unordered_set& operator=(unordered_set&&) @@ -324,22 +324,22 @@ public: unordered_multiset(initializer_list, size_type n = /see below/, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_multiset(size_type n, const allocator_type& a); // C++14 - unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); // C++14 + unordered_multiset(size_type n, const allocator_type& a); + unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); template - unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); // C++14 + unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); template unordered_multiset(InputIterator f, InputIterator l, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); template R> unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hasher(), key_equal(), a) { } // C++23 template R> unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(from_range, std::forward(rg), n, hf, key_equal(), a) { } // C++23 - unordered_multiset(initializer_list il, size_type n, const allocator_type& a); // C++14 + unordered_multiset(initializer_list il, size_type n, const allocator_type& a); unordered_multiset(initializer_list il, size_type n, - const hasher& hf, const allocator_type& a); // C++14 + const hasher& hf, const allocator_type& a); ~unordered_multiset(); unordered_multiset& operator=(const unordered_multiset&); unordered_multiset& operator=(unordered_multiset&&) @@ -634,12 +634,10 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_set() _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) {} explicit _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const allocator_type& __a) : unordered_set(__n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__n, __hf, key_equal(), __a) {} -# endif _LIBCPP_HIDE_FROM_ABI unordered_set(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); template @@ -677,7 +675,6 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI unordered_set(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) @@ -686,7 +683,6 @@ public: _LIBCPP_HIDE_FROM_ABI unordered_set( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__first, __last, __n, __hf, key_equal(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -717,14 +713,12 @@ public: const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_set(__il, __n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_set(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_set(__il, __n, __hf, key_equal(), __a) {} -# endif # endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI ~unordered_set() { static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); @@ -1250,12 +1244,10 @@ public: unordered_multiset(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const allocator_type& __a) : unordered_multiset(__n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__n, __hf, key_equal(), __a) {} -# endif template _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last); template @@ -1291,7 +1283,6 @@ public: } # endif -# if _LIBCPP_STD_VER >= 14 template inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(_InputIterator __first, _InputIterator __last, size_type __n, const allocator_type& __a) @@ -1300,7 +1291,6 @@ public: inline _LIBCPP_HIDE_FROM_ABI unordered_multiset( _InputIterator __first, _InputIterator __last, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) {} -# endif # if _LIBCPP_STD_VER >= 23 template <_ContainerCompatibleRange _Range> @@ -1331,14 +1321,12 @@ public: const hasher& __hf, const key_equal& __eql, const allocator_type& __a); -# if _LIBCPP_STD_VER >= 14 inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list __il, size_type __n, const allocator_type& __a) : unordered_multiset(__il, __n, hasher(), key_equal(), __a) {} inline _LIBCPP_HIDE_FROM_ABI unordered_multiset(initializer_list __il, size_type __n, const hasher& __hf, const allocator_type& __a) : unordered_multiset(__il, __n, __hf, key_equal(), __a) {} -# endif # endif // _LIBCPP_CXX03_LANG _LIBCPP_HIDE_FROM_ABI ~unordered_multiset() { static_assert(sizeof(std::__diagnose_unordered_container_requirements<_Value, _Hash, _Pred>(0)), ""); diff --git a/libcxx/include/vector b/libcxx/include/vector index f289013a682bc..b136cca1f6050 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -39,7 +39,7 @@ public: noexcept(is_nothrow_default_constructible::value); explicit vector(const allocator_type&); explicit vector(size_type n); - explicit vector(size_type n, const allocator_type&); // C++14 + explicit vector(size_type n, const allocator_type&); vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); @@ -171,7 +171,7 @@ public: vector() noexcept(is_nothrow_default_constructible::value); explicit vector(const allocator_type&) noexcept; - explicit vector(size_type n, const allocator_type& a = allocator_type()); // C++14 + explicit vector(size_type n, const allocator_type& a = allocator_type()); vector(size_type n, const value_type& value, const allocator_type& = allocator_type()); template vector(InputIterator first, InputIterator last, const allocator_type& = allocator_type()); diff --git a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp index 014f9c5960e5b..ce2b2ef185d90 100644 --- a/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/map/map.cons/iter_iter_comp_alloc.pass.cpp @@ -72,7 +72,6 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin()) == V(2, 1)); assert(*std::next(m.begin(), 2) == V(3, 1)); } -# if TEST_STD_VER > 11 { typedef std::pair V; V ar[] = { @@ -113,7 +112,6 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(m.get_allocator() == a); } } -# endif #endif return true; } diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp index fb3f4b831cc0d..08320024cc5bd 100644 --- a/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/iter_iter_comp_alloc.pass.cpp @@ -115,6 +115,46 @@ bool test() { assert(*std::next(m.begin(), 7) == V(3, 1.5)); assert(*std::next(m.begin(), 8) == V(3, 2)); } + { + typedef std::pair V; + V ar[] = { + V(1, 1), + V(1, 1.5), + V(1, 2), + V(2, 1), + V(2, 1.5), + V(2, 2), + V(3, 1), + V(3, 1.5), + V(3, 2), + }; + { + typedef min_allocator A; + typedef test_less C; + A a; + std::multimap m(ar, ar + sizeof(ar) / sizeof(ar[0]), a); + + assert(m.size() == 9); + assert(std::distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*std::next(m.begin(), 3) == V(2, 1)); + assert(*std::next(m.begin(), 6) == V(3, 1)); + assert(m.get_allocator() == a); + } + { + typedef explicit_allocator A; + typedef test_less C; + A a; + std::multimap m(ar, ar + sizeof(ar) / sizeof(ar[0]), a); + + assert(m.size() == 9); + assert(std::distance(m.begin(), m.end()) == 9); + assert(*m.begin() == V(1, 1)); + assert(*std::next(m.begin(), 3) == V(2, 1)); + assert(*std::next(m.begin(), 6) == V(3, 1)); + assert(m.get_allocator() == a); + } + } #endif return true; diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp index 22ac9bd799e45..ffb655fa8ade5 100644 --- a/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/iter_iter_alloc.pass.cpp @@ -48,7 +48,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin(), 7) == 3); assert(*std::next(m.begin(), 8) == 3); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; diff --git a/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp b/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp index 60167a566145a..c15e05bcc309e 100644 --- a/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp +++ b/libcxx/test/std/containers/associative/set/set.cons/iter_iter_alloc.pass.cpp @@ -46,7 +46,7 @@ TEST_CONSTEXPR_CXX26 bool test() { assert(*std::next(m.begin()) == 2); assert(*std::next(m.begin(), 2) == 3); } -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 { typedef int V; V ar[] = {1, 1, 1, 2, 2, 2, 3, 3, 3}; diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp index f8f42bd668f83..c31caa6c2d414 100644 --- a/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/deque/deque.cons/size.pass.cpp @@ -9,6 +9,7 @@ // // explicit deque(size_type n); +// explicit deque(size_type n, const Allocator& a); #include "asan_testing.h" #include @@ -22,7 +23,7 @@ template void test2(unsigned n) { -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 typedef std::deque C; typedef typename C::const_iterator const_iterator; assert(DefaultOnly::count == 0); @@ -62,7 +63,7 @@ void test1(unsigned n) { template void test3(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 typedef std::deque C; { C d(n, alloc); @@ -102,7 +103,7 @@ int main(int, char**) { test >(4095); #endif -#if TEST_STD_VER > 11 +#if TEST_STD_VER >= 11 test3>(1023); test3>(1); test3>(3); diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp index 206854560c19f..89baa06dec475 100644 --- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/size.pass.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // // explicit forward_list(size_type n); // constexpr since C++26 @@ -21,15 +23,10 @@ template void check_allocator(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 typedef std::forward_list C; C d(n, alloc); assert(d.get_allocator() == alloc); assert(static_cast(std::distance(d.begin(), d.end())) == n); -#else - ((void)n); - ((void)alloc); -#endif } int main(int, char**) { @@ -46,14 +43,24 @@ int main(int, char**) { unsigned n = 0; for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n) { -#if TEST_STD_VER >= 11 assert(*i == T()); -#else - ((void)0); -#endif } assert(n == N); } + { + typedef DefaultOnly T; + typedef std::forward_list > C; + unsigned N = 10; + C c(N, std::allocator()); + unsigned n = 0; + + for (C::const_iterator i = c.begin(), e = c.end(); i != e; ++i, ++n) { + assert(*i == T()); + } + assert(n == N); + check_allocator >(0); + check_allocator >(3); + } #if TEST_STD_VER >= 11 { typedef DefaultOnly T; diff --git a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp index 55371e8354a9e..4992400c406d7 100644 --- a/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp +++ b/libcxx/test/std/containers/sequences/list/list.cons/size_type.pass.cpp @@ -6,9 +6,12 @@ // //===----------------------------------------------------------------------===// +// XFAIL: FROZEN-CXX03-HEADERS-FIXME + // -// explicit list(size_type n); // constexpr since C++26 +// explicit list(size_type n); // constexpr since C++26 +// explicit list(size_type n, const Allocator& a); // constexpr since C++26 #include #include @@ -21,7 +24,6 @@ template TEST_CONSTEXPR_CXX26 void test1(unsigned n, Allocator const& alloc = Allocator()) { -#if TEST_STD_VER > 11 typedef std::list C; { C d(n, alloc); @@ -29,10 +31,6 @@ TEST_CONSTEXPR_CXX26 void test1(unsigned n, Allocator const& alloc = Allocator() assert(static_cast(std::distance(d.begin(), d.end())) == n); assert(d.get_allocator() == alloc); } -#else - ((void)n); - ((void)alloc); -#endif } TEST_CONSTEXPR_CXX26 bool test() { @@ -59,7 +57,19 @@ TEST_CONSTEXPR_CXX26 bool test() { ++i; assert(*i == 0); } -#if TEST_STD_VER > 11 + { + std::list > l(3, std::allocator()); + assert(l.size() == 3); + assert(std::distance(l.begin(), l.end()) == 3); + std::list >::const_iterator i = l.begin(); + assert(*i == 0); + ++i; + assert(*i == 0); + ++i; + assert(*i == 0); + test1 >(3); + } +#if TEST_STD_VER >= 11 { typedef std::list > C; C l(3, min_allocator()); diff --git a/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp index 80b3fe307c93a..f97396d67ae9d 100644 --- a/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector.bool/construct_size.pass.cpp @@ -10,6 +10,7 @@ // vector // explicit vector(size_type n); +// explicit vector(size_type n, const Allocator& alloc = Allocator()); #include #include @@ -21,7 +22,7 @@ template TEST_CONSTEXPR_CXX20 void test2(typename C::size_type n, typename C::allocator_type const& a = typename C::allocator_type()) { -#if TEST_STD_VER >= 14 +#if TEST_STD_VER >= 11 C c(n, a); LIBCPP_ASSERT(c.__invariants()); assert(c.size() == n); diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp index cbae3653d995f..0902a4070b7aa 100644 --- a/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp +++ b/libcxx/test/std/containers/sequences/vector/vector.cons/construct_size.pass.cpp @@ -38,7 +38,7 @@ test(typename C::size_type n, typename C::allocator_type const& a = typename C:: } // Test with a custom allocator -#if TEST_STD_VER >= 14 +#if TEST_STD_VER >= 11 { C c(n, a); LIBCPP_ASSERT(c.__invariants()); diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp index e29ecea327971..3fd4e7fcfa5f5 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp index c2adf98c7eaca..31d4ce0adf437 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp index 1039e1d92be79..bf1536dd0b44a 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp index b6e06df9c8fe2..a5f9ddeb0d825 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp index 450fb7b5e40d4..8e4d7ff8e1fbe 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp index a9f73f3f45fe2..19bbb305fe10f 100644 --- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp index 7ec2dd2efb895..a8371367f7ead 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp index eab5d60fbf6f4..ec566bb75a2f9 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp index ad6ad9d1ad1ef..5e694b5d5ed3a 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp index ee35b36cf7519..7592b10b792ec 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp index d49be5518922a..70798e3920a7d 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp index f26fae2a2a81d..42d75cfa28ba0 100644 --- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp index bb0cc2441bfb7..314e60381dfcc 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp index 24b802f4fcca2..f962ddd8f0344 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp index 994ec058fae94..6eb48201d116c 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp index 138af889d5978..44e572e10071f 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp index e536644470122..ddf0a4d02b932 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp index 6ea22dab1aac9..531215e0671e3 100644 --- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp index 7346a951b1976..90c6d9720e90c 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp index 704fff0f51cca..306ec62c81d7b 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/init_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp index 414485466d71e..bdd2d841283a6 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp index ba986eba5f71c..48d64a8860e23 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/iter_iter_size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp index 99abd12745eca..6af94925a5a2b 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp index e44854eb0a132..11c3e7bd2ee0c 100644 --- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp +++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/size_hash_allocator.pass.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03, c++11 +// UNSUPPORTED: c++03 // From 76066e5867611b7ed87e4f8eb8f18dc6ec479855 Mon Sep 17 00:00:00 2001 From: Jared Wyles Date: Fri, 10 Jul 2026 10:01:14 +1000 Subject: [PATCH 051/125] [orc_rt] adding a very simple CLI flags parser in (#172987) Adds orc_rt::CommandLineParser, a small header-only option parser in orc-rt-utils for use by orc-rt tools that need argument handling. Features: - Long (--name, --name=value) and short (-n, -nvalue) options. - Short-flag clustering (e.g. -vp9999) and "--" to terminate option parsing, with remaining tokens collected as positionals. - Typed values, with parse failures returning an orc_rt::Error. - printHelp() with aligned, optionally short-name-aware output. Values are bound to caller-owned storage supplied at registration time and reset to their defaults on each parse(). Also adds CommandLineTest.cpp to the CoreTests unittest and fixes the indentation of the docs subdirectory guard in orc-rt/CMakeLists.txt. --- orc-rt/include/orc-rt-utils/CommandLine.h | 256 ++++++++++++++++++++++ orc-rt/test/unit/CMakeLists.txt | 1 + orc-rt/test/unit/CommandLineTest.cpp | 145 ++++++++++++ 3 files changed, 402 insertions(+) create mode 100644 orc-rt/include/orc-rt-utils/CommandLine.h create mode 100644 orc-rt/test/unit/CommandLineTest.cpp diff --git a/orc-rt/include/orc-rt-utils/CommandLine.h b/orc-rt/include/orc-rt-utils/CommandLine.h new file mode 100644 index 0000000000000..3582d88bb7df6 --- /dev/null +++ b/orc-rt/include/orc-rt-utils/CommandLine.h @@ -0,0 +1,256 @@ +//===- CommandLine.h ------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Simple orc-rt command-line parser. Supports flags, values and positionals. +// All storage owned by caller. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "orc-rt/Error.h" + +namespace orc_rt { +namespace detail { + +template inline std::optional parseValue(std::string_view Str); + +template <> +inline std::optional +parseValue(std::string_view Str) { + return std::string(Str); +} + +template <> +inline std::optional +parseValue(std::string_view Str) { + return Str; +} + +template <> inline std::optional parseValue(std::string_view Str) { + if (Str.empty()) + return std::nullopt; + int Val{}; + auto Ret = std::from_chars(Str.data(), Str.data() + Str.size(), Val); + if (Ret.ec != std::errc() || Ret.ptr != Str.data() + Str.size()) + return std::nullopt; + return Val; +} + +template <> inline std::optional parseValue(std::string_view Str) { + if (Str.empty()) + return std::nullopt; + + if (Str == "1") + return true; + if (Str == "0") + return false; + + std::string Val; + std::transform( + Str.begin(), Str.end(), std::back_inserter(Val), + [](unsigned char C) { return static_cast(std::tolower(C)); }); + + if (Val == "true") + return true; + if (Val == "false") + return false; + + return std::nullopt; +} +} // namespace detail + +class CommandLineParser { +public: + enum class OptionKind { Flag, Value }; + CommandLineParser() = default; + + CommandLineParser &addFlag(std::string_view Name, std::string_view Desc, + bool DefaultVal, bool &Val, + std::optional ShortName = std::nullopt) { + return addValue(Name, Desc, DefaultVal, Val, OptionKind::Flag, + std::move(ShortName)); + } + + template + CommandLineParser &addValue(std::string_view Name, std::string_view Desc, + T DefaultVal, T &Val, + OptionKind Kind = OptionKind::Value, + std::optional ShortName = std::nullopt) { + Val = DefaultVal; + Opts.push_back({.Name = std::string(Name), + .ShortName = std::move(ShortName), + .Desc = std::string(Desc), + .Kind = Kind, + .Default = [&Val, DV = DefaultVal]() { Val = DV; }, + .FromString = [&Val, OptName = std::string(Name)]( + std::string_view S) -> orc_rt::Error { + if (auto V = detail::parseValue(S)) { + Val = *V; + return orc_rt::Error::success(); + } + return orc_rt::make_error( + std::string("Invalid value for '") + OptName + + "': '" + std::string(S) + "'"); + }}); + return *this; + } + + void printHelp(std::ostream &OS, std::string_view ProgramName) const { + OS << "Usage: " << ProgramName << " [options] [positional arguments]\n\n"; + OS << "OPTIONS:\n"; + + bool AnyShortNames = + std::any_of(Opts.begin(), Opts.end(), + [](const Option &O) { return O.ShortName.has_value(); }); + + size_t MaxWidth = 0; + for (const auto &Opt : Opts) { + size_t CurrentWidth = 2; // " " + if (AnyShortNames) + CurrentWidth += 4; // "-x, " + CurrentWidth += 2 + Opt.Name.length(); // "--name" + if (Opt.Kind == OptionKind::Value) + CurrentWidth += 8; // " " + MaxWidth = std::max(MaxWidth, CurrentWidth); + } + + for (const auto &Opt : Opts) { + std::string FlagStr = " "; + if (AnyShortNames) { + if (Opt.ShortName) { + FlagStr += "-"; + FlagStr += *Opt.ShortName; + FlagStr += ", "; + } else { + FlagStr += " "; // Pad gutter + } + } + FlagStr += "--" + Opt.Name; + if (Opt.Kind == OptionKind::Value) + FlagStr += " "; + + OS << std::left << std::setw(MaxWidth + 2) << FlagStr << Opt.Desc << "\n"; + } + } + + template orc_rt::Error parse(I Begin, I End) { + std::for_each(Opts.begin(), Opts.end(), + [](const Option &O) { O.Default(); }); + Positionals.clear(); + bool AfterDashDash = false; + if (Begin != End) + Begin++; + + for (auto It = Begin; It != End; ++It) { + std::string_view Tok(*It); + if (!AfterDashDash && Tok == "--") { + AfterDashDash = true; + continue; + } + if (!AfterDashDash && startsWith(Tok, "--")) { + std::string_view K = Tok.substr(2); + std::string_view V; + bool HasValue = false; + if (auto P = K.find('='); P != std::string_view::npos) { + V = K.substr(P + 1); + K = K.substr(0, P); + HasValue = true; + } + auto FoundOpt = findOpt(K); + if (!FoundOpt) + return orc_rt::make_error( + "Unknown option '" + std::string(Tok) + "'"); + if (auto Err = consumeValue(FoundOpt, V, HasValue, It, End)) + return Err; + } else if (!AfterDashDash && startsWith(Tok, "-") && Tok.size() > 1) { + std::string_view Group = Tok.substr(1); + for (size_t i = 0; i < Group.size(); ++i) { + auto FoundOpt = findOpt(Group[i]); + if (!FoundOpt) + return orc_rt::make_error( + std::string("Unknown short option '-") + Group[i] + "'"); + if (FoundOpt->Kind == OptionKind::Value) { + std::string_view V = Group.substr(i + 1); + bool HasValue = !V.empty(); + if (auto Err = consumeValue(FoundOpt, V, HasValue, It, End)) + return Err; + break; + } else { + if (auto Err = FoundOpt->FromString("true")) + return Err; + } + } + } else { + Positionals.emplace_back(Tok); + } + } + return orc_rt::Error::success(); + } + + orc_rt::Error parse(int argc, char **argv) { + return parse(argv, argv + argc); + } + + const std::vector &positionals() const { return Positionals; } + +private: + struct Option { + std::string Name; + std::optional ShortName; + std::string Desc; + OptionKind Kind{}; + std::function Default; + std::function FromString; + }; + + std::vector Positionals; + std::vector